DF-3200 / verdict.json
{ "finding_id": "DF-3200", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "The u_char truncation itself is arithmetic certainty from source: devfs_rule_alloc() assigns strlen() into u_char fields (devfs_rules.h:53-59), so a 256-char name stores namlen 0 and devfs_rule_create_link() evaluates rule->name[rule->namlen-1] == rule->name[-1] - a one-byte heap over-read before the kstrdupd name deciding the wildcard branch; mntpointlen truncation likewise makes devfs_rule_clear() remove rules for 256+-char mntoints on a 44-byte prefix match and makes len%256==0 rules unclearable. Runtime isolation was not possible on the stock kernel: any 256-char NAME pattern that still matches a node requires >=250 *s, which first exhausts the stack in wildCaseCmp (DF-3202) - the first double fault of this session (252-star pattern) is exactly that interaction. Hence inconclusive at runtime, certain from source; the fix removes the class and the fixed kernel rejects the pattern family at rule-add.", "exploit_chain": "", "evidence": [ "VERDICT.md: derivation of name[-1] read and clear confusion", "DF-3202/panic.txt: the 252-star 256-char pattern double fault (the entanglement)", "run.fixed.log: pattern rejected at ADD, no OOB path reachable" ], "kernel_refs": [ "sys/sys/devfs_rules.h:53", "sys/sys/devfs_rules.h:56", "sys/sys/devfs_rules.h:59", "sys/vfs/devfs/devfs_rules.c:97", "sys/vfs/devfs/devfs_rules.c:110", "sys/vfs/devfs/devfs_rules.c:124", "sys/vfs/devfs/devfs_rules.c:243", "sys/vfs/devfs/devfs_rules.c:200-204" ], "poc_changes": "initial 255-a+* pattern matched no node (branch never reached); switched to stars+null+stars which matches but collides with DF-3202", "attempts": 3, "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": 10, "guest_dirty": 1, "build_cmd": "cc -static -O -o trunc_namlen trunc_namlen.c", "run_cmd": "./trunc_namlen", "code_hash": "2b5b20dd6e6d33c63c778d77ab31c79ad5d899afd1f677afa744a1da14eba162", "notes": "Low severity: privileged trigger, one-byte OOB read / wrong-branch and rule-clear confusion", "recommended_fix": "u_int16_t length fields in struct devfs_rule + reject len >= PATH_MAX at rule-add", "fix_status": "fixed", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Tue Sep 8 10:25:07 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fixed kernel stores full lengths (u_int16_t) and rejects the star-heavy 256-char patterns at ADD (EINVAL), so neither name[-1] nor the truncated clear compare is reachable", "fix_evidence": [ "DF-3200/run.fixed.log" ] } |