Index: stand/i386/libi386/biosdisk.c =================================================================== --- stand/i386/libi386/biosdisk.c +++ stand/i386/libi386/biosdisk.c @@ -845,9 +845,10 @@ struct dsk dskp; off_t p_off, diff; daddr_t alignlba; - int err, n, alignblks; + int err, n, alignblks, shortread; char *tmpbuf; + shortread = 0; /* if we already know there is no GELI, skip the rest */ if (geli_status[dev->dd.d_unit][dev->d_slice] != ISGELI_YES) return (bd_io(dev, dblk, blks, dest, 0)); @@ -882,10 +883,13 @@ } } + /* Don't read past the end of the disk */ if (alignlba + alignblks > BD(dev).bd_sectors) { DEBUG("Shorted read at %llu from %d to %llu blocks", alignlba, alignblks, BD(dev).bd_sectors - alignlba); alignblks = BD(dev).bd_sectors - alignlba; + /* If we can't read an entire 4k, we can't decrypt it */ + shortread = 1; } err = bd_io(dev, alignlba, alignblks, tmpbuf, 0); @@ -902,10 +906,18 @@ /* GELI needs the offset relative to the partition start */ p_off = alignlba - dskp.start; - err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, (u_char *)tmpbuf, - alignblks * BD(dev).bd_sectorsize); - if (err) - return (err); + /* Only decrypt reads from inside the encrypted partition boundry */ + if (dskp.start > 0 && dblk >= dskp.start && shortread == 0) { + err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, (u_char *)tmpbuf, + alignblks * BD(dev).bd_sectorsize); + if (err) + return (err); + } else { + DEBUG("bd_read: Not decrypting read from %lld, " + "outside of partition bounds: lower=%llu, " + "upper=%llu, shortread=%d\n", dblk, dskp.start, + BD(dev).bd_sectors, shortread); + } if (tmpbuf != dest) { bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize);