DF-3339 / verdict.json
{ "finding_id": "DF-3339", "status": "reproduced", "reproduced": 1, "impact": "dos", "confidence": "certain", "verdict": "REPRODUCED (deterministic): pfr_add_tables() allocates the ktable and increments rs->tables BEFORE scanning addq for duplicates, then goto _skip discards the pointer on a duplicate batch element. Two identical pfr_table entries in one DIOCRADDTABLES leak ~1.4KB (vmstat: 3 pfrktable allocs for 1 usable table; kldunload: malloc_uninit: 2816 bytes of pfrktable still allocated) and permanently drift pf_main_ruleset.tables vs the RB tree, so every subsequent DIOCRGETTABLES prints pfr_get_tables: corruption detected (2). and returns ENOTTY - pfctl -s Tables fails until reboot. Root-only, deterministic; Low severity.", "exploit_chain": "root sends one DIOCRADDTABLES containing [T,T] -> ktable leak + rs->tables drift -> all table listing ioctls for the ruleset return ENOTTY until reboot (admin-plane DoS) + unbounded repeatable leak.", "evidence": [ "run.log: [1] nadd=1, [3] DIOCRGETTABLES rc=-1 errno=25, dmesg corruption line, vmstat 3 allocs", "kernel source pf_table.c:1170-1182 (create-before-dup-check)" ], "kernel_refs": [ "sys/net/pf/pf_table.c:1170", "sys/net/pf/pf_table.c:1172", "sys/net/pf/pf_table.c:1175", "sys/net/pf/pf_table.c:1297" ], "poc_changes": "added #include <net/if.h> for pfvar.hs IFNAMSIZ; nothing else - first run reproduced.", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 30, "guest_dirty": 0, "build_cmd": "cd /tmp/poc/DF-3339 && sh build.sh", "run_cmd": "cd /tmp/poc/DF-3339 && sh run.sh", "code_hash": "0a9c7238b5d4c1f5c6df6262ea8004d899b1b07056a298a9e9a66c1b213082ba", "notes": "Same pattern exists un-exploited in the root-table creation path (pf_table.c:1191-1196) only when the same name+anchor appears twice, which the RB/addq check covers; the kt-creation leak is the reachable one. Low severity, fix not kernel-validated to conserve guest budget.", "recommended_fix": "In pfr_add_tables(), scan addq for the duplicate before pfr_create_ktable() (or destroy the fresh table and decrement rs->tables on the _skip path).", "fix_status": "not_testable" } |