⬢ DragonFlyBSD Kernel Audit
DF-3104 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3104",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "leak",
 "confidence": "certain",
 "verdict": "udf_timetotimespec() indexes mon_lens[lpyear][i] for i = 1..month-1 using the unvalidated uint8_t month from the on-disk timestamp; months 13..255 read up to ~1 KB of kernel static .data past the 2x12 int array and the summed words are observable via stat() st_mtime differences. Reproduced as uid 1001 on a crafted image: 19/19 month terms for months >= 13 (leap-year row) were out-of-range words, e.g. first OOB term mon_lens[1][12] (flat index 24). FreeBSD carries the identical fix with the comment Dont trust time->month as it will be used for an array index.",
 "exploit_chain": "crafted UDF image (or any image with corrupt timestamps) -> unprivileged stat() of files whose FE mtime month = 13..255 -> per-word recovery (25/32 bits each, 86400 = 2^7*675) of kernel .data adjacent to mon_lens at build-deterministic offsets -> KASLR-defeat / kernel-build fingerprint oracle. Read-only, low bandwidth, hence Low severity.",
 "evidence": [
  "run.log: T11/T12 diffs in-range (2592000/2678400), T13..T31 all OUT-OF-RANGE diffs ending in DF3104_OOB_CONFIRMED: 19 of the month terms ...",
  "leak_sample.txt: full st_mtime table",
  "fix_run.log: patched module -> every month>=13 st_mtime clamped to 0",
  "craft_img.py: T10..T31 FEs with year=2020 (leap), month=10..31"
 ],
 "kernel_refs": [
  "sys/vfs/udf/udf_vnops.c:220",
  "sys/vfs/udf/udf_vnops.c:267",
  "sys/vfs/udf/udf_vnops.c:268"
 ],
 "poc_changes": "Seed PoC authored fresh for pass 2; one iteration (shared <fcntl.h> fix). No obstacles.",
 "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": 120,
 "guest_dirty": 0,
 "build_cmd": "cc -O2 -Wall -o /tmp/df3102_poc /tmp/df3102_poc.c (guest); python3 craft_img.py df3102.udf (host)",
 "run_cmd": "./run.sh (host driver: mount as root; su maxx -c /tmp/df3102_poc ts /mnt)",
 "code_hash": "b50456f09049a3a3f9cecccbf847b544c5408e238f3831a07660d0c0ed0b9d2a",
 "notes": "Low severity on this guest (no KASLR) but a genuine disk-fed array-index violation with a one-line upstream-proven fix; verified because the PoC rides the same image as DF-3102/3103 at zero extra cost.",
 "recommended_fix": "Validate the timestamp in udf_timetotimespec: reject year < 1970 || month < 1 || month > 12 (clamp tv_sec to 0), matching FreeBSD.",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 (same kernel; udf.ko module rebuilt from patched /usr/src/sys/vfs/udf and kldloaded)",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "With the month validation in the patched module, every file with month >= 13 reports st_mtime 0 (epoch clamp) instead of garbage sums; months <= 12 keep correct values (fix_run.log).",
 "fix_evidence": [
  "fix_run.log",
  "fix_build.log",
  "fix.diff",
  "df31xx_combined_fix.diff"
 ]
}