⬢ DragonFlyBSD Kernel Audit
DF-3111 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer/hammer_subs.c
+++ b/sys/vfs/hammer/hammer_subs.c
@@ -1031,6 +1031,21 @@
 		hpanic("bad algorithm %p", dip);
 		break;
 	}
+
+	/*
+	 * Clamp the iteration count so the consumers' unchecked
+	 * 'cursor.key_end.key += max_iterations' (hammer_vnops.c:
+	 * hammer_vop_nlookup / hammer_vop_nrename / hammer_dounlink)
+	 * cannot overflow the positive key space.  Directory keys only
+	 * use the positive key space (see hammer_ip_add_direntry()).
+	 * Without the clamp a crafted filename whose namekey lands in
+	 * the top 0xFFFFFF of the key space wraps key_end negative and
+	 * truncates the hash-chain scan: the dirent becomes permanently
+	 * unfindable and unremovable.
+	 */
+	if (key > 0x7FFFFFFFFFFFFFFFLL - (int64_t)*max_iterationsp)
+		*max_iterationsp = (uint32_t)(0x7FFFFFFFFFFFFFFFLL - key);
+
 	return(key);
 }