GELIBoot may attempt to read past the end of the disk

Usually there is some slack after the last partition due to 4k alignment
In the 10.3 EC2 images, there was not. EC2 seems to hang if you try to
read past the end of the disk in the loader, resulting in an unbootable
instance after upgrading to 11.0

PR:		213196
Reported by:	Peter Ankerstal <peter@pean.org>
Tested by:	cperciva
Reviewed by:	tsoome
MFC after:	3 days
Sponsored by:	ScaleEngine Inc.
Differential Revision:	https://reviews.freebsd.org/D8144
This commit is contained in:
Allan Jude 2016-10-04 16:33:03 +00:00
parent f7948591dc
commit 452bd5bf51

View File

@ -77,17 +77,25 @@ geli_taste(int read_func(void *vdev, void *priv, off_t off, void *buf,
int error;
off_t alignsector;
alignsector = (lastsector * DEV_BSIZE) &
~(off_t)(DEV_GELIBOOT_BSIZE - 1);
alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE);
if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) {
/* Don't read past the end of the disk */
alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE
- DEV_GELIBOOT_BSIZE;
}
error = read_func(NULL, dskp, alignsector, &buf, DEV_GELIBOOT_BSIZE);
if (error != 0) {
return (error);
}
/* Extract the last DEV_BSIZE bytes from the block. */
error = eli_metadata_decode(buf + (DEV_GELIBOOT_BSIZE - DEV_BSIZE),
&md);
/* Extract the last 4k sector of the disk. */
error = eli_metadata_decode(buf, &md);
if (error != 0) {
return (error);
/* Try the last 512 byte sector instead. */
error = eli_metadata_decode(buf +
(DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md);
if (error != 0) {
return (error);
}
}
if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {