⬢ DragonFlyBSD Kernel Audit
DF-3200 / verdict.json
← back to finding ↓ download raw
{
  "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"
  ]
}