DragonFlyBSD Kernel Audit
DF-0769 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c
--- a/sys/vfs/hammer/hammer_vnops.c
+++ b/sys/vfs/hammer/hammer_vnops.c
@@ -1725,6 +1725,19 @@
 			break;
 		base = &cursor.leaf->base;
 		saveoff = base->key;
+		/*
+		 * Validate the on-disk direntry data_len before using it.
+		 * A corrupted or forged B-tree leaf can carry data_len <=
+		 * HAMMER_ENTRY_NAME_OFF, which underflows the name length
+		 * computed below and (on INVARIANTS-OFF kernels) drives a
+		 * ~49 KB out-of-bounds read in vop_write_dirent().  Reject
+		 * any leaf whose data_len is not a plausible direntry size.
+		 */
+		if (cursor.leaf->data_len <= HAMMER_ENTRY_NAME_OFF ||
+		    cursor.leaf->data_len > HAMMER_ENTRY_NAME_OFF + NAME_MAX) {
+			error = EIO;
+			break;
+		}
 		KKASSERT(cursor.leaf->data_len > HAMMER_ENTRY_NAME_OFF);
 
 		if (base->obj_id != ip->obj_id)