DF-5470 / run.log
DF-5470 — actual run transcript (baseline, stock kernel, then fix.diff) Guest: DragonFly 6.5-DEVELOPMENT #0 (stock X86_64_GENERIC), fresh boot. === BASELINE === # state of msgbuf before the attack (this is what a panic would need to preserve): root@dfbsd# dmesg | tail -4 hammer2: enable read/write HAMMER2: VOLDATA DUMP HAMMER2: INITIATE SPANs swap low/high-water marks set to 41940/62910 root@dfbsd# sysctl -w debug.df_count=30000 debug.df_count: 1024 -> 30000 # unprivileged user (uid 1001) sprays 40000 fake frames at user VA # 0x60000000 and triggers the production db_stack_trace_cmd() from its own # syscall context: maxx@dfbsd$ /tmp/user_chain; echo EXIT=$? USERCHAIN: base=0x60000000 nframes=40000 ktext=0xffffffdebfab7d78 (uid=1001) USERCHAIN: walk triggered+returned EXIT=0 # msgbuf after: root@dfbsd# dmesg | grep -c "DFTRACE: goq: walking" # walk's own start line 0 root@dfbsd# dmesg | grep -c "swap low/high-water" # boot context 0 root@dfbsd# dmesg | wc -l 22754 root@dfbsd# dmesg | head -3 ffdebfab7d78 (null)() at -0x2140548288 0xffffffdebfab7d78 (null)() at -0x2140548288 0xffffffdebfab7d78 root@dfbsd# dmesg | tail -3 (null)() at -0x2140548288 0xffffffdebfab7d78 (null)() at -0x2140548288 0xffffffdebfab7d78 DFTRACE: goq: walk returned => The production backtracer walked 30000 attacker-sprayed frames in UNPRIVILEGED USER address space, pushing 22754+ lines (~1.07MB, MSGBUF_SIZE=1MB) into msgbuf and evicting every trace of the pre-walk buffer content, including the walk's own start line and the boot context. (Each line shows the attacker-chosen callpc; the first 7000+ lines were themselves evicted by the tail of the same walk.) === PATCHED (fix.diff: INKERNEL() + monotonic-forward frame validation) === # same steps on the kernel built with fix.diff: root@dfbsd# dmesb | grep -c "(null)() at" # [sic] dmesg 0 root@dfbsd# dmesg | grep "not in kernel space" 0x60000000 is not in kernel space root@dfbsd# dmesg | grep -c "swap low/high-water" # boot context survives 1 root@dfbsd# dmesg | tail -3 DFTRACE: goq: walking chain at 0x60000000, count 30000 0x60000000 is not in kernel space DFTRACE: goq: walk returned => walk refuses to leave kernel space; no flood; msgbuf intact.