โฌข DragonFlyBSD Kernel Audit
DF-2132 / run.log
โ† back to finding โ†“ download raw
================================================================
DF-2132 baseline reproduction record (UNPATCHED production drm.ko)
guest: DragonFly 6.5-DEVELOPMENT X86_64_GENERIC (INVARIANTS)
trigger user: nobody (uid 65534) via /dev/df2132 (0666)
================================================================

----------------------------------------------------------------
[1] MODE A โ€” refcount oracle (2 runs, clean exits) [run_A.log]
----------------------------------------------------------------
df2132_user: mode A (pid 823 uid 65534)
usched_set(cpu 0) failed rc=-1 (continuing; reclaim may be nondeterministic)
export      : dmabuf fd=4 fp=0xfffff80116da4180 (f_count=2: falloc-ref + fd-table-ref)
resting f_count BEFORE import: 3
import#1     fd= 4 fcount 3->2 rel=0 slot_valid=0 slot_is_saved=0 fp=0x0 (saved 0x0)
resting f_count AFTER  import: 2
ORACLE: resting count DROPPED 3->2 across one get/put pair => dma_buf_put() fdrop()s a ref nobody acquired: BUG PRESENT
mode A done, exited cleanly
rcA=0
df2132_user: mode A (pid 827 uid 65534)
usched_set(cpu 0) failed rc=-1 (continuing; reclaim may be nondeterministic)
export      : dmabuf fd=4 fp=0xfffff80116da3f00 (f_count=2: falloc-ref + fd-table-ref)
resting f_count BEFORE import: 3
import#1     fd= 4 fcount 3->2 rel=0 slot_valid=0 slot_is_saved=0 fp=0x0 (saved 0x0)
resting f_count AFTER  import: 2
ORACLE: resting count DROPPED 3->2 across one get/put pair => dma_buf_put() fdrop()s a ref nobody acquired: BUG PRESENT
mode A done, exited cleanly
rcA2=0

----------------------------------------------------------------
[2] MODE B โ€” premature free + dangling-close panic [serial console]
    (full capture: logs/panic_modeB_final.txt / panic_modeB_full.txt)
----------------------------------------------------------------
df2132: [export] cpu3 dma_buf fd=4 fp=0xfffff80116da4180 f_count=2 (falloc-ref + fd-table-ref)
df2132: [import] cpu3 fd=4 f_count 3->2 (over-drop: put consumed a ref nobody acquired)
df2132: [fo_close] ops->release() ran: release_count=1 (struct file freed by dma_buf_put/fdrop while fd-table slot may still reference it)
df2132: [export] cpu3 dma_buf fd=4 fp=0xfffff80116da3f00 f_count=2 (falloc-ref + fd-table-ref)
df2132: [import] cpu3 fd=4 f_count 3->2 (over-drop: put consumed a ref nobody acquired)
df2132: [fo_close] ops->release() ran: release_count=2 (struct file freed by dma_buf_put/fdrop while fd-table slot may still reference it)
login: df2132: [export] cpu2 dma_buf fd=4 fp=0xfffff80116c4ce00 f_count=2 (falloc-ref + fd-table-ref)
df2132: [import] cpu2 fd=4 f_count 3->2 (over-drop: put consumed a ref nobody acquired)
df2132: [import] cpu2 fd=4 f_count 2->1 (over-drop: put consumed a ref nobody acquired)
df2132: [fo_close] ops->release() ran: release_count=3 (struct file freed by dma_buf_put/fdrop while fd-table slot may still reference it)
df2132: [import] cpu2 fd=4 f_count 1->0: *** STRUCT FILE FREED INSIDE dma_buf_put WHILE FD-TABLE SLOT STILL REFERENCES IT ***
df2132: [info] fd=4 release_count=3 slot_valid=1 slot_is_saved=1 freed-fp=0xfffff80116c4ce00
df2132: [user] mode B: premature free CONFIRMED, slot dangling
panic: fdrop: invalid f_count -1
fdrop() at fdrop+0x10e 0xffffffff806314de 
fdrop() at fdrop+0x10e 0xffffffff806314de 
closef() at closef+0x32 0xffffffff80631f22 
kern_close() at kern_close+0xef 0xffffffff8063212f 
syscall2() at syscall2+0x11e 0xffffffff80bd6a0e 
Debugger("panic")
Stopped at      Debugger+0x7c:  movb    $0,0xbdaf09(%rip)

----------------------------------------------------------------
[3] MODE c โ€” reclaim + alias + functional UAF read + silent steal
    [user-side record: run_c.out; console: logs/dmesg_mode_c.txt,
     logs/panic_modeC_full.txt]
----------------------------------------------------------------
df2132_user: mode c (pid 964 uid 65534)
usched_set(cpu 0) failed rc=-1 (continuing; reclaim may be nondeterministic)
export      : dmabuf fd=4 fp=0xfffff80116daf700 (f_count=2: falloc-ref + fd-table-ref)
import       fd= 4 fcount 3->2 rel=0 slot_valid=0 slot_is_saved=0 fp=0x0 (saved 0x0)
import       fd= 4 fcount 2->1 rel=0 slot_valid=0 slot_is_saved=0 fp=0x0 (saved 0x0)
import       fd= 4 fcount 1->0 rel=0 slot_valid=0 slot_is_saved=0 fp=0x0 (saved 0x0)
info         fd= 4 fcount 0->0 rel=1 slot_valid=1 slot_is_saved=1 fp=0x0 (saved 0xfffff80116daf700)
PREMATURE FREE CONFIRMED (freed fp 0xfffff80116daf700, dangling fd 4)
phase-1: dummy file fd=952 REOCCUPIED the freed chunk after ~960 allocations
phase-2: /dev/null fd=952 LANDED ON the freed chunk (fp=0xfffff80116daf700)
read(dangling fd=4) = 0  <== UAF read through freed-then-reclaimed struct file
closing aliased fd 952 (silent steal: frees object while dangling fd still references it)
mode c: parking 300s with dangling fd 4 held open (exit would close it and panic)