Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Oct 2016 16:50:10 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r307930 - releng/11.0/sys/boot/geli
Message-ID:  <201610251650.u9PGoAAc064968@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Tue Oct 25 16:50:10 2016
New Revision: 307930
URL: https://svnweb.freebsd.org/changeset/base/307930

Log:
  EN-16:18: loader may hang during boot
  
  A programming error in GELIBoot causes the loader to attempt to read past
  the end of the disk if the size of the final partition is not a multiple of
  4 kB.
  
  Merge r306834 from stable/11.
  
  Approved by:	so

Modified:
  releng/11.0/sys/boot/geli/geliboot.c
Directory Properties:
  releng/11.0/   (props changed)

Modified: releng/11.0/sys/boot/geli/geliboot.c
==============================================================================
--- releng/11.0/sys/boot/geli/geliboot.c	Tue Oct 25 16:45:55 2016	(r307929)
+++ releng/11.0/sys/boot/geli/geliboot.c	Tue Oct 25 16:50:10 2016	(r307930)
@@ -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)) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610251650.u9PGoAAc064968>