โฌข DragonFlyBSD Kernel Audit
DF-0850 / panic.txt
โ† back to finding โ†“ download raw
=== DF-0850 PANIC SIGNATURE (unpatched #0 kernel) ===
Trigger: mount crafted ext2 image (DIRHASHINDEX + inode IN_E3INDEX +
interior htree node with count=limit=0xFFFF) then stat a file in the dir.

panic: lockmgr: locking against myself
cpuid = 5
Trace beginning at frame 0xfffff80117abb138
lockmgr_exclusive() at lockmgr_exclusive+0x3e0 0xffffffff80647f30 
lockmgr_exclusive() at lockmgr_exclusive+0x3e0 0xffffffff80647f30 
getblk() at getblk+0xe1 0xffffffff806d6f91 
breadnx() at breadnx+0x284 0xffffffff806d7714 
ext2_blkatoff() at ext2_blkatoff+0x58 0xffffffff8260a1e8 
ext2_htree_find_leaf() at ext2_htree_find_leaf+0x1e5 0xffffffff82605ac5 
Debugger("panic")

=== Root Cause ===
ext2_htree_find_leaf (ext2_htree.c:312-342) walks the htree. At the root
(lines 308-310) the limit is validated against ext2_htree_root_limit().
After descending into an interior node (lines 335-339, entp = node->h_entries),
the NEXT iteration's limit check (line 314: cnt > get_limit(entp)) reads the
limit from the attacker-controlled on-disk interior node header โ€” NOT validated
against ext2_htree_node_limit(). With count=limit=0xFFFF, the binary search
(line 321: get_hash(middle)) reads OOB past the bp->b_data buffer. The OOB
data feeds get_block(found) โ†’ ext2_blkatoff with a garbage block number โ†’
getblk tries to re-lock an already-held buffer โ†’ lockmgr panic.