Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Feb 2019 19:16:28 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r344295 - in stable/11/stand: common i386/libi386 i386/zfsboot
Message-ID:  <201902191916.x1JJGSU3042487@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Tue Feb 19 19:16:28 2019
New Revision: 344295
URL: https://svnweb.freebsd.org/changeset/base/344295

Log:
  MFC r335245-r335248, r335254, r335276, r335298, r335398, r335868, r335883
  
  r335245:
  Correct logic error in biosdisk.c:bd_realstrategy()
  
  The wrong condition is used when evaluating the return of disk_ioctl()
  This results in reaching the 'We should not get here' branch in most casts
  
  r335246:
  biosdisk.c remove redundant variable
  
  `rdev` and `disk` serve the same purpose, read the partition table without
  the `d_offset` or `d_slice` set, so the read is relative to the start of
  the disk. Reuse the already initialized `disk` instead of making another
  copy later.
  
  r335247:
  biosdisk.c: add missing \n to error message
  
  r335248:
  biosdisk.c: fix type in debug printf
  
  r335254:
  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.
  
  r335276:
  gptboot, zfsboot, gptzfsboot: Enable the video and serial consoles early
  
  Normally the serial console is not enabled until /boot.config is read and
  we know how the serial console should be configured.  Initialize the
  consoles early in 'dual' mode (serial & keyboard) with a default serial
  rate of 115200. Then serial is re-initialized once the disk is decrypted
  and the /boot.config file can be read.
  
  This allows the GELIBoot passphrase to be provided via the serial console.
  
  r335298:
  stand/common/disk.c: Update debug printf
  
  This was missed in r330809 because it is compiled out by default
  
  r335398:
  Revert r335276
  
  This was causing issues for people booting.
  I will likely bring this back as an optional feature, similar to
  boot0sio, like gptboot-serial or something.
  
  r335868:
  stand/common/disk.c: Read partition table relative to the start of the disk
  
  If a disk is of an oddball size, like the 200mb + 512b used in rootgen.sh,
  when disk_open() is called on a GELI encrypted partition, attempts to read
  the partition table fail, as they pass through the decryption process which
  turns the already plaintext data into jibberish.
  
  When reading the partition table, always pass a slice and partition setting
  of -1, and an offset of 0. Setting the slice to -1 prevents a false
  positive when checking the slice against the cache of GELI encrypted
  slices.
  
  r335883:
  stand/common/disk.c: dev->d_offset still needs to be set to 0
  
  With r335868, I thought this was no longer necessary. I was wrong.

Modified:
  stable/11/stand/common/disk.c
  stable/11/stand/i386/libi386/biosdisk.c
  stable/11/stand/i386/zfsboot/zfsboot.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/stand/common/disk.c
==============================================================================
--- stable/11/stand/common/disk.c	Tue Feb 19 19:15:15 2019	(r344294)
+++ stable/11/stand/common/disk.c	Tue Feb 19 19:16:28 2019	(r344295)
@@ -219,20 +219,13 @@ disk_ioctl(struct disk_devdesc *dev, u_long cmd, void 
 int
 disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
 {
+	struct disk_devdesc partdev;
 	struct open_disk *od;
 	struct ptable *table;
 	struct ptable_entry part;
 	int rc, slice, partition;
 
 	rc = 0;
-	/*
-	 * While we are reading disk metadata, make sure we do it relative
-	 * to the start of the disk
-	 */
-	dev->d_offset = 0;
-	table = NULL;
-	slice = dev->d_slice;
-	partition = dev->d_partition;
 	od = (struct open_disk *)malloc(sizeof(struct open_disk));
 	if (od == NULL) {
 		DEBUG("no memory");
@@ -242,11 +235,25 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize
 	od->entrysize = 0;
 	od->mediasize = mediasize;
 	od->sectorsize = sectorsize;
+	/*
+	 * While we are reading disk metadata, make sure we do it relative
+	 * to the start of the disk
+	 */
+	memcpy(&partdev, dev, sizeof(partdev));
+	partdev.d_offset = 0;
+	partdev.d_slice = -1;
+	partdev.d_partition = -1;
+
+	dev->d_offset = 0;
+	table = NULL;
+	slice = dev->d_slice;
+	partition = dev->d_partition;
+
 	DEBUG("%s unit %d, slice %d, partition %d => %p",
-	    disk_fmtdev(dev), dev->d_unit, dev->d_slice, dev->d_partition, od);
+	    disk_fmtdev(dev), dev->dd.d_unit, dev->d_slice, dev->d_partition, od);
 
 	/* Determine disk layout. */
-	od->table = ptable_open(dev, mediasize / sectorsize, sectorsize,
+	od->table = ptable_open(&partdev, mediasize / sectorsize, sectorsize,
 	    ptblread);
 	if (od->table == NULL) {
 		DEBUG("Can't read partition table");

Modified: stable/11/stand/i386/libi386/biosdisk.c
==============================================================================
--- stable/11/stand/i386/libi386/biosdisk.c	Tue Feb 19 19:15:15 2019	(r344294)
+++ stable/11/stand/i386/libi386/biosdisk.c	Tue Feb 19 19:16:28 2019	(r344295)
@@ -379,7 +379,7 @@ bd_print(int verbose)
 static int
 bd_open(struct open_file *f, ...)
 {
-	struct disk_devdesc *dev, rdev;
+	struct disk_devdesc *dev;
 	struct disk_devdesc disk;
 	int err, g_err;
 	va_list ap;
@@ -445,11 +445,8 @@ bd_open(struct open_file *f, ...)
 	dskp.part = dev->d_partition;
 	dskp.start = dev->d_offset;
 
-	memcpy(&rdev, dev, sizeof(rdev));
-	/* to read the GPT table, we need to read the first sector */
-	rdev.d_offset = 0;
 	/* We need the LBA of the end of the partition */
-	table = ptable_open(&rdev, BD(dev).bd_sectors,
+	table = ptable_open(&disk, BD(dev).bd_sectors,
 	    BD(dev).bd_sectorsize, ptblread);
 	if (table == NULL) {
 		DEBUG("Can't read partition table");
@@ -594,8 +591,8 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s
 	*rsize = 0;
 
     /* Get disk blocks, this value is either for whole disk or for partition */
-    if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks)) {
-	/* DIOCGMEDIASIZE does return bytes. */
+    if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
+	/* DIOCGMEDIASIZE returns bytes. */
         disk_blocks /= BD(dev).bd_sectorsize;
     } else {
 	/* We should not get here. Just try to survive. */
@@ -622,7 +619,7 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s
 	if (blks && (rc = bd_read(dev, dblk, blks, buf))) {
 	    /* Filter out floppy controller errors */
 	    if (BD(dev).bd_flags != BD_FLOPPY || rc != 0x20) {
-		printf("read %d from %lld to %p, error: 0x%x", blks, dblk,
+		printf("read %d from %lld to %p, error: 0x%x\n", blks, dblk,
 		    buf, rc);
 	    }
 	    return (EIO);
@@ -638,7 +635,7 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s
 #endif
 	break;
     case F_WRITE :
-	DEBUG("write %d from %d to %p", blks, dblk, buf);
+	DEBUG("write %d from %lld to %p", blks, dblk, buf);
 
 	if (blks && bd_write(dev, dblk, blks, buf)) {
 	    DEBUG("write error");
@@ -883,6 +880,12 @@ bd_read(struct disk_devdesc *dev, daddr_t dblk, int bl
 			if (tmpbuf == NULL) {
 				return (-1);
 			}
+		}
+
+		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);

Modified: stable/11/stand/i386/zfsboot/zfsboot.c
==============================================================================
--- stable/11/stand/i386/zfsboot/zfsboot.c	Tue Feb 19 19:15:15 2019	(r344294)
+++ stable/11/stand/i386/zfsboot/zfsboot.c	Tue Feb 19 19:16:28 2019	(r344295)
@@ -209,6 +209,12 @@ vdev_read(void *xvdev, void *priv, off_t off, void *bu
 		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);
     }
 



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