DragonFlyBSD Kernel Audit
DF-2662 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_iocom.c
+++ b/sys/vfs/hammer2/hammer2_iocom.c
@@ -311,8 +311,19 @@
 				     HAMMER2_KEY_MIN, HAMMER2_KEY_MAX,
 				     &error, 0);
 	while (chain) {
-		if (chain->bref.type != HAMMER2_BREF_TYPE_INODE)
+		/*
+		 * DF-2662: A chain whose data failed to load (e.g. EIO)
+		 * has chain->data == NULL and must not be dereferenced.
+		 * Also advance the iteration for skipped chains (the old
+		 * bare `continue` looped forever on non-INODE entries).
+		 */
+		if (chain->bref.type != HAMMER2_BREF_TYPE_INODE ||
+		    chain->data == NULL) {
+			chain = hammer2_chain_next(&parent, chain, &key_next,
+						   key_next, HAMMER2_KEY_MAX,
+						   &error, 0);
 			continue;
+		}
 		ripdata = &chain->data->ipdata;
 #if 0
 		kprintf("UPDATE SPANS: %s\n", ripdata->filename);