svn commit: r306677 - head/sys/boot/geli

Allan Jude allanjude at FreeBSD.org
Tue Oct 4 16:33:04 UTC 2016


Author: allanjude
Date: Tue Oct  4 16:33:03 2016
New Revision: 306677
URL: https://svnweb.freebsd.org/changeset/base/306677

Log:
  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 at pean.org>
  Tested by:	cperciva
  Reviewed by:	tsoome
  MFC after:	3 days
  Sponsored by:	ScaleEngine Inc.
  Differential Revision:	https://reviews.freebsd.org/D8144

Modified:
  head/sys/boot/geli/geliboot.c

Modified: head/sys/boot/geli/geliboot.c
==============================================================================
--- head/sys/boot/geli/geliboot.c	Tue Oct  4 16:29:26 2016	(r306676)
+++ head/sys/boot/geli/geliboot.c	Tue Oct  4 16:33:03 2016	(r306677)
@@ -77,17 +77,25 @@ geli_taste(int read_func(void *vdev, voi
 	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)) {


More information about the svn-src-all mailing list