⬢ DragonFlyBSD Kernel Audit
DF-3448 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3448",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "sysctl_ip6_tempvltime() in sys/netinet6/in6_proto.c:437-453 restores the wrong variable on the EINVAL path: a rejected net.inet6.ip6.tempvltime write PERSISTS in the kernel, and ip6_temp_preferred_lifetime is simultaneously clobbered with the old valid lifetime. Verified live on the stock INVARIANTS guest (2/2 deterministic runs): after sysctl -w net.inet6.ip6.tempvltime=100 fails with EINVAL (pltime=86400), tempvltime reads back 100 and temppltime reads back 604800. Root-only config corruption of RFC 4941 temporary-address lifetimes; no memory-safety impact. The twin handler sysctl_ip6_temppltime and the KAME/FreeBSD original restore correctly; this is a DragonFly transcription bug.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3448/run.log and run.2.log \u2014 decisive lines: sysctl: net.inet6.ip6.tempvltime=100: Invalid argument followed by pltime=604800  vltime=100 and both BUG PART n CONFIRMED lines; VERDICT.md has the full path:line trace; fix.diff is the one-word correction",
  "kernel_refs": [
    "sys/netinet6/in6_proto.c:437",
    "sys/netinet6/in6_proto.c:448",
    "sys/netinet6/in6_proto.c:450",
    "sys/netinet6/in6_proto.c:495"
  ],
  "poc_changes": "none \u2014 pure shell trigger written fresh (no seed); no compilation required",
  "attempts": 2,
  "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": 12,
  "guest_dirty": 0,
  "build_cmd": "none (shell-only PoC; see build.sh)",
  "run_cmd": "sh /tmp/df3448_trigger.sh  (as root on guest)",
  "code_hash": "f0dcc6694d69e24f86b45c8b4ecbd9cf8e23d47669aa82438de298233b2ef775",
  "notes": "Guest sysctls restored to defaults (86400/604800) after the runs; guest otherwise untouched. Notable trap: sysctl(8) prints the OLD value in its failure diagnostic while the kernel variable is left at the rejected one.",
  "recommended_fix": "In sysctl_ip6_tempvltimes rejection path, restore ip6_temp_valid_lifetime = old (not ip6_temp_preferred_lifetime), matching the sysctl_ip6_temppltime twin and the KAME/FreeBSD original",
  "fix_status": "not_testable",
  "fix_kernel_uname": null,
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": null,
  "fix_verdict": "fix.diff restores the correct variable (one-word change mirroring the pltime handler and upstream KAME code); kernel rebuild validation skipped \u2014 mandatory only for memory-corruption findings, and this Low logic fix is verifiable by inspection",
  "fix_evidence": "findings/poc/DF-3448/fix.diff"
}