⬢ DragonFlyBSD Kernel Audit
DF-3696 / manifest.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3696",
 "verdict": {
  "finding_id": "DF-3696",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "In DEGRADED state the RAID5 branch of ata_raid_strategy falls through an empty 'XOR game' placeholder: the per-chunk ata_request allocated at :386 is neither queued nor freed and the bio is never completed. With a crafted Promise/FreeBSD RAID5 metadata disk (width=2, total_disks=2, one disk absent) the array assembled DEGRADED at boot and the kernel's own ar0 slice-scan bio hung forever - boot wedged before ssh, serial log stops exactly at the ar0 lines, hard reset required. Same hole hangs every read/write and leaks one ata_request per chunk on legitimately-built degraded RAID5 arrays.",
  "exploit_chain": "crafted disk -> DEGRADED ar0 at boot -> kernel slice-scan bio -> empty branch at :609-611 -> no biodone, request leaked -> boot wedge (persistent DoS); repeatable 100%",
  "evidence": "run.log/panic.txt (serial stops after the 3 ar0 lines; missing 'MBR magic' line proves the probe read never completed), run.patched.log (fixed kernel boots to login, I/O fails EIO)",
  "kernel_refs": [
   "sys/dev/disk/nata/ata-raid.c:386",
   "sys/dev/disk/nata/ata-raid.c:609",
   "sys/dev/disk/nata/ata-raid.c:611",
   "sys/dev/disk/nata/ata-raid.c:955"
  ],
  "poc_changes": "first fix iteration used ata_free_request() on the never-queued request and tripped the CALLOUT_DID_INIT assert in callout_terminate (a latent flaw the pre-existing error paths at :423/:449/:624 share); corrected to bzero+objcache_put and re-validated",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 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": 320,
  "guest_dirty": 0,
  "build_cmd": "python3 mkmeta.py (host); image f7_r5deg.img on ata0-master",
  "run_cmd": "ARAID_DRIVE=/tmp/opencode/araid/f7_r5deg.img dfbsd-qemu/vm.sh up 220  (expect wedge; RUN timeout)",
  "code_hash": "",
  "notes": "CWE-401 (request leak) + CWE-835 (unkillable biowait).",
  "recommended_fix": "fail the bio with EIO and free the un-queued request via bzero+objcache_put in the DEGRADED branch (fix.diff hunk 4, v2)",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "v2 patched kernel boots with the same DEGRADED array, I/O errors cleanly, reaches login (see run.patched.log); v1 lesson documented in poc_changes",
  "fix_evidence": "run.patched.log"
 },
 "reproduce": {
  "build": "python3 mkmeta.py (host); attach image as QEMU ata0-master (vm.sh ARAID_DRIVE)",
  "run": "ARAID_DRIVE=f7_r5deg.img  dfbsd-qemu/vm.sh up  (boot wedge)",
  "expected": "serial stops after ar0 DEGRADED lines; ssh never up"
 },
 "kernel_refs": [
  "sys/dev/disk/nata/ata-raid.c:386",
  "sys/dev/disk/nata/ata-raid.c:609",
  "sys/dev/disk/nata/ata-raid.c:611"
 ],
 "artifacts": [
  "README.md",
  "VERDICT.md",
  "mkmeta.py",
  "build.sh",
  "run.sh",
  "run.log",
  "panic.txt",
  "run.patched.log",
  "fix.diff",
  "env.txt",
  "verdict.json",
  "manifest.json"
 ],
 "code_hash": "19b6ef7de08eec487c4b3111586d4e9e39dce900a4d6e3c138efa9783daa8f22"
}