⬢ DragonFlyBSD Kernel Audit
DF-3165 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/udf/udf_vfsops.c
+++ b/sys/vfs/udf/udf_vfsops.c
@@ -371,6 +371,16 @@
 	 */
 	sector = udfmp->root_icb.loc.lb_num + udfmp->part_start;
 	size = udfmp->root_icb.len;
+	/*
+	 * The root file entry is at most one logical block; larger (or
+	 * wrapped) on-disk lengths would panic getblk ("size > MAXBSIZE")
+	 * or hand udf_readlblks() a negative int size.
+	 */
+	if (size == 0 || size > MAXBSIZE) {
+		kprintf("Invalid root file entry length %u\n", size);
+		error = EINVAL;
+		goto bail;
+	}
 	if ((error = udf_readlblks(udfmp, sector, size, &bp)) != 0) {
 		kprintf("Cannot read sector %d\n", sector);
 		goto bail;
@@ -659,6 +669,16 @@
 		}
 
 		pms = &pmap->pms;
+		/*
+		 * st_size is an on-disk u32: unchecked it flows into
+		 * kmalloc() and udf_readlblks() -> bread() -> getblk(),
+		 * which panics once the rounded size exceeds MAXBSIZE.
+		 */
+		if (pms->st_size == 0 || pms->st_size > MAXBSIZE) {
+			kprintf("Invalid sparing table size %u\n",
+			    pms->st_size);
+			return (1);
+		}
 		udfmp->s_table = kmalloc(pms->st_size, M_UDFMOUNT,
 					M_WAITOK | M_ZERO);