DragonFlyBSD Kernel Audit
DF-0929 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/hammer/hammer_btree.c b/sys/vfs/hammer/hammer_btree.c
--- a/sys/vfs/hammer/hammer_btree.c
+++ b/sys/vfs/hammer/hammer_btree.c
@@ -731,9 +731,21 @@
 		return(0);
 
 	/*
-	 * Load the data
+	 * Load the data.
+	 *
+	 * data_len is an int32_t read directly from the on-disk B-Tree leaf
+	 * element and is attacker-controlled on a crafted filesystem image.
+	 * Validate it explicitly here rather than relying on the KKASSERT
+	 * below, which is compiled out on kernels built without INVARIANTS.
+	 * A bogus data_len would otherwise drive an out-of-bounds read in
+	 * hammer_bread_ext()/bcmp() and integer overflow in the blockmap
+	 * DOALIGN macros (see DF-0929).
 	 */
-	KKASSERT(data_len >= 0 && data_len <= HAMMER_XBUFSIZE);
+	if (data_len < 0 || data_len > HAMMER_XBUFSIZE) {
+		hdkprintf("bad data_len %d for leaf @ %016jx\n",
+			data_len, (intmax_t)elm->leaf.data_offset);
+		return (EIO);
+	}
 	cursor->data = hammer_bread_ext(hmp, data_off, data_len,
 					&error, &cursor->data_buffer);