DragonFlyBSD Kernel Audit
DF-0883 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c
--- a/sys/vfs/udf/udf_vfsops.c
+++ b/sys/vfs/udf/udf_vfsops.c
@@ -304,6 +304,21 @@
 		lvd = (struct logvol_desc *)bp->b_data;
 		if (!udf_checktag(&lvd->tag, TAGID_LOGVOL)) {
 			udfmp->bsize = lvd->lb_size;
+			/*
+			 * Validate the logical block size: it must be a
+			 * non-zero power of two in [DEV_BSIZE, MAXBSIZE].
+			 * A zero or non-power-of-2 value drives a divide-
+			 * by-zero (udf_find_partmaps) and corrupts all
+			 * block-masking arithmetic.
+			 */
+			if (lvd->lb_size < DEV_BSIZE ||
+			    lvd->lb_size > MAXBSIZE ||
+			    (lvd->lb_size & (lvd->lb_size - 1)) != 0) {
+				kprintf("udf: invalid logical block size %u\n",
+				    lvd->lb_size);
+				error = EINVAL;
+				goto bail;
+			}
 			udfmp->bmask = udfmp->bsize - 1;
 			udfmp->bshift = ffs(udfmp->bsize) - 1;
 			fsd_part = lvd->_lvd_use.fsd_loc.loc.part_num;