DragonFlyBSD Kernel Audit
DF-1603 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/virtual/virtio/block/virtio_blk.c b/sys/dev/virtual/virtio/block/virtio_blk.c
--- a/sys/dev/virtual/virtio/block/virtio_blk.c
+++ b/sys/dev/virtual/virtio/block/virtio_blk.c
@@ -699,7 +699,17 @@
 	/* construct the disk_info */
 	bzero(&info, sizeof(info));
 
-	if (virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_BLK_SIZE))
+	/*
+	 * Validate blk_size: the virtio-blk specification permits the backend
+	 * to advertise VIRTIO_BLK_F_BLK_SIZE with any u32 value (including 0),
+	 * and we divide by sc->vtblk_sector_size below (line 712). A 0 or
+	 * non-power-of-2 value would either panic the kernel via a #DE trap
+	 * (DF-1603) or produce nonsense geometry. Fall back to the spec's
+	 * implicit default of 512B whenever the reported value is malformed.
+	 */
+	if (virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_BLK_SIZE) &&
+	    blkcfg->blk_size >= DEV_BSIZE &&
+	    powerof2(blkcfg->blk_size))
 		sc->vtblk_sector_size = blkcfg->blk_size;
 	else
 		sc->vtblk_sector_size = 512;