{
  "finding_id": "DF-5521",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED: iicsmb_detach (iicsmb.c:164-175) performs no quiesce -- no busy refcount, no drain, no iicbus-ownership check, and it ignores bus_generic_detach()s error before deleting its smbus child -- while every SMBus client transaction routed through the bridge holds the iicbus (smb.c:240-243,356 via iicsmb_callback -> iicbus_request_bus) and can be asleep inside iicbus_read()/write(). devclass_delete_driver (subr_bus.c:853-899) force-detaches and the kldunload then frees module text. Live proof on the QEMU guest with a software-controller rig running the production chain (isa->dfa_iic0->iicbus0->iicsmb0->smbus0->smb0, /dev/smb0): kldunload iicsmb mid-BREAD -> smb0/smbus0/iicsmb0: detached -> the sleeper wakes -> Fatal trap 12, fault virtual address = 0xffffffff8261f0bf == inside the unloaded iicsmb.ko text range (kldstat: 0xffffffff8261f000+0xe000) -> execution of freed module code (2 crash modes observed; second: smbus_release_bus+0x78 on the freed smbus0, fault VA 0x0). Post-unload, iicbus_softc->owner dangles for the next iicbus_intr (iiconf.c:50-51). Root-gated (kldunload + /dev/smb0 0600) => severity Low. FIX VALIDATED: guard iicsmb_detach with EBUSY while iicbus_bus_owned() + the symmetric smbus_detach owner guard (required because iicsmb.c:510s DRIVER_MODULE(smbus, iicsmb) lets the unload tear the smbus child down WITHOUT calling iicsmb_detach -- observed live); patched modules + rebuilt kernel: mid-BREAD kldunload refused (Device busy), in-flight ioctls complete normally, clean unload after quiesce, post-unload INTR_STOP is a no-op, guest alive.",
  "exploit_chain": "root (or root-driven kernel client e.g. ipmi_ssif poller) issues /dev/smb0 SMB_BREAD -> smbus_request_bus sets iicbus_softc->owner=iicsmb0 for the whole ioctl -> controller polling sleeps inside iicbus_read under the bridge -> concurrent kldunload iicsmb force-detaches smb0/smbus0/iicsmb0 (smbus_detach/iicsmb_detach return 0 unconditionally in stock code) and frees iicsmb.ko text + the smbus0 device -> sleeper resumes at a return address inside freed module text -> Fatal trap 12 (or returns through to smbus_release_bus on the freed smbus0 -> fault VA 0x0). No unprivileged trigger path exists (device node 0600 root:wheel); this is a privileged-user/kernel-lifecycle UAF, not an escalation primitive.",
  "evidence": "panic.txt (decisive: iicsmb0: detached then sleeper wakes, Fatal trap 12 ... 0xffffffff8261f0bf ... supervisor read instruction, page not present, current process = the BREAD child; address inside the unloaded iicsmb.ko range from run.logs kldstat); run.log (full baseline session incl. module addresses); run.fixed.log (kldunload: cant unload file: Device busy mid-BREAD, clean unload after client stops, guest alive); fix.diff; df5521_rig.c / df5521_poc.c (race + racefixed modes)",
  "kernel_refs": [
    "sys/bus/iicbus/iicsmb.c:164",
    "sys/bus/iicbus/iicsmb.c:175",
    "sys/bus/iicbus/iicsmb.c:509",
    "sys/bus/iicbus/iicsmb.c:510",
    "sys/bus/iicbus/iiconf.c:45",
    "sys/bus/iicbus/iiconf.c:50",
    "sys/bus/iicbus/iiconf.c:85",
    "sys/bus/iicbus/iiconf.c:141",
    "sys/kern/subr_bus.c:853",
    "sys/kern/subr_bus.c:899",
    "sys/dev/smbus/smb/smb.c:240",
    "sys/dev/smbus/smb/smb.c:356",
    "sys/bus/smbus/smbus.c:108"
  ],
  "poc_changes": "no seed PoC existed (pass-2 discovery, the pcf.c audits kldunload-not-pinned lead developed here); wrote df5521_rig.c (software iicbus controller on isa registering DRIVER_MODULE(iicbus, dfa_iic,...), wire-logged, hw.dfa.rdelay in-flight window, hw.dfa.fire_event ISR injector) + df5521_poc.c. Fixes during development: (1) extern iicbus_driver decls conflicted with iicbus.h (-Werror=redundant-decls); (2) rig modevent must run AFTER DRIVER_MODULE handlers (SI_ORDER_MIDDLE+1); (3) racefixed resolves the kld id from kldstat (path-loaded modules are not unloadable by name); (4) the PoCs looping child holds stdout -- run it detached with output to a file.",
  "attempts": 9,
  "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": 9600,
  "guest_dirty": 0,
  "build_cmd": "guest: sh build.sh (make in /usr/src/sys/bus/iicbus/df5521 -> df5521_rig.ko; cc -O -o df5521_poc df5521_poc.c); fix build: patch -p1 < fix.diff in /usr/src, make in sys/bus/iicbus/{iicbus,iicsmb}, sys/dev/smbus/smb, plus make nativekernel KERNCONF=X86_64_GENERIC && make installkernel (smbus is compiled into the kernel), reboot",
  "run_cmd": "vm.sh run_root sh /root/load_chain.sh; sysctl hw.dfa.rdelay=300; /root/df5521_poc race   # baseline: Fatal trap 12 in freed iicsmb.ko text (serial console); fixed: /root/df5521_poc racefixed -> Device busy + clean unload + guest alive",
  "code_hash": "16fea8b1ba1d070dbd19dae52d1bcdaa1d4d6aeb3c9d4ad4d534a430677d5eb4",
  "notes": "Cross-file observations routed for other audits: (a) smbioctls SMB_BREAD passes an UNINITIALIZED u_char bcount into smbus_bread (smb.c:217,323) -- observed as bridge transfer length 0 in one process and 255 in another (see DF-5523); (b) the pcf.c audits wildcard children not attaching lead does NOT reproduce as an iicsmb.c defect: with iicsmb.ko/smb.ko loaded before the iicbus attaches, the wildcard children (ic/iic/iicsmb -> smbus -> smb) attach fine (live: iicsmb0/smbus0/smb0 and /dev/smb0). DF-5490s non-attach was a missing DRIVER_MODULE on the pcf side; (c) iicbus.ko unloading while iicbus0 is attached is the same unpinned-unload class (iicbus.c has no guard either). Guest reset with-src after testing.",
  "recommended_fix": "iicsmb.c: refuse detach while the bridge owns the iicbus (new iicbus_bus_owned() accessor in iiconf.c/iiconf.h; return EBUSY) + propagate bus_generic_detach errors; smbus.c: smbus_detach returns EBUSY while sc->owner != NULL (closes the smbus/iicsmb driver-module teardown path of iicsmb.c:510). See fix.diff (validated live).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "Baseline (stock iicbus.ko/iicsmb.ko/smb.ko/smbus-in-kernel): 1/1 rig runs panic -- Fatal trap 12 at 0xffffffff8261f0bf (freed iicsmb.ko text) after mid-BREAD kldunload; second crash mode smbus_release_bus+0x8 fault VA 0x0 observed twice during fix development. Patched (fix.diff: iicbus_bus_owned + iicsmb_detach EBUSY + smbus_detach EBUSY; kernel rebuilt because smbus is compiled into X86_64_GENERIC): 1/1 clean -- mid-BREAD kldunload refused with Device busy, childs in-flight ioctls complete normally, unload succeeds after the client stops, post-unload INTR_STOP no-op, guest alive. Residual (documented): a complete fix would pin the module across smbus_request_bus/release rather than refusing detach; every demonstrated window is closed by the guards.",
  "fix_evidence": "run.fixed.log; run.log + panic.txt (before/after); fix.diff"
}