Avoid reading past the end of the disk in zfsboot.c and biosdisk.c

The GELI boot code rounds reads up to 4k, since the encrypted sectors are
4k, and must be decrypted as a unit. With oddball sized disks (almost
always virtual), this can lead to reading past the end of the disk.

Reviewed by:	imp, tsoome
Sponsored by:	Klara Systems
Differential Revision:	https://reviews.freebsd.org/D15844
This commit is contained in:
Allan Jude 2018-06-16 15:16:02 +00:00
parent f39bffc62c
commit 71f0c895c1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=335254
2 changed files with 14 additions and 2 deletions

View File

@ -882,6 +882,12 @@ bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
}
}
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;
}
err = bd_io(dev, alignlba, alignblks, tmpbuf, 0);
if (err)
return (err);

View File

@ -209,6 +209,12 @@ vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes)
alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE)
/ DEV_BSIZE;
if (dsk->size > 0 && alignlba + alignnb > dsk->size + dsk->start) {
printf("Shortening read at %lld from %d to %lld\n", alignlba,
alignnb, (dsk->size + dsk->start) - alignlba);
alignnb = (dsk->size + dsk->start) - alignlba;
}
if (drvread(dsk, dmadat->rdbuf, alignlba, alignnb))
return -1;
#ifdef LOADER_GELI_SUPPORT
@ -694,7 +700,7 @@ main(void)
dsk->slice = *(uint8_t *)PTOV(ARGS + 1) + 1;
dsk->part = 0;
dsk->start = 0;
dsk->size = 0;
dsk->size = drvsize_ext(dsk);
bootinfo.bi_version = BOOTINFO_VERSION;
bootinfo.bi_size = sizeof(bootinfo);
@ -745,7 +751,7 @@ main(void)
dsk->slice = 0;
dsk->part = 0;
dsk->start = 0;
dsk->size = 0;
dsk->size = drvsize_ext(dsk);
probe_drive(dsk);
}