DF-3305 / verdict.json
{ "finding_id": "DF-3305", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "del_vif() does not stop tbf_reprocess_q_ch which tbf_control() armed with vifp; del_vif bzeros the vif (v_tbf=NULL) and the 10ms callout fires into tbf_update_tokens() which reads t->tbf_last_pkt_t at NULL+0x8: Fatal trap 12, Stopped at tbf_update_tokens.isra.11+0x2a subq 0x8(%rbx),%rax, on iteration 0. Root-only trigger (MRT_DEL_VIF) so Low severity, but deterministic and a plain daemon-restart sequence can hit it. Fixed kernel stops the callout in del_vif and guards v_tbf==NULL: 200 iterations, no panic.", "exploit_chain": "root: MRT_INIT -> MRT_ADD_VIF(phyint, rate_limit>0) -> MRT_ADD_MFC -> inject one matching multicast (queues in tbf, arms 10ms callout with vifp) -> MRT_DEL_VIF (bzero, v_tbf=NULL, callout not stopped) -> callout fires -> tbf_update_tokens derefs NULL -> panic.", "evidence": [ "run.log: iter 0 sent, DEL_VIF rc=0 then Fatal trap 12", "panic.txt: fault virtual address 0x8, Stopped at tbf_update_tokens.isra.11+0x2a subq 0x8(%rbx),%rax", "fix_run.log: no panic after 200 iterations" ], "kernel_refs": [ "sys/net/ip_mroute/ip_mroute.c:1791", "sys/net/ip_mroute/ip_mroute.c:873", "sys/net/ip_mroute/ip_mroute.c:908", "sys/net/ip_mroute/ip_mroute.c:1873", "sys/net/ip_mroute/ip_mroute.c:1966", "sys/net/ip_mroute/ip_mroute.c:1972" ], "poc_changes": "First version never reached the vif: a raw socket without imo gets ip_ttl forced to 1 by ip_output and X_ip_mforward drops TTL<=1. Added IP_MULTICAST_TTL=5 (+loop off) on the raw socket -> panic on iteration 0.", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Sep 10 09:22:03 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/PIMTEST x86_64", "runtime_sec": 120, "guest_dirty": 1, "build_cmd": "cc -O2 -Wall -o tbfcallout tbfcallout.c", "run_cmd": "./tbfcallout", "code_hash": "ebdefca2f673af3cf67fef90ab560defb108639b6c203fc51a49a10fcfbd9a89", "notes": "X_ip_mrouter_done stops the callout (:644) - del_vif forgot. Same global callout is reused for all vifs, so stopping it in del_vif only delays other vifs queues until their next packet (acceptable).", "recommended_fix": "del_vif(): callout_stop(&tbf_reprocess_q_ch) before bzero; tbf_reprocess_q(): return if vifp==NULL || vifp->v_tbf==NULL.", "fix_status": "fixed", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Thu Sep 10 10:33:47 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/PIMTEST x86_64", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Patched kernel: tbfcallout runs 200 add/send/del cycles, no panic after 200 iterations (fix_run.log). Baseline panicked on iteration 0.", "fix_evidence": "fix_run.log; fix_build.log" } |