{
  "finding_id": "DF-5559",
  "status": "reproduced",
  "reproduced": true,
  "impact": "none",
  "confidence": "certain",
  "verdict": "REPRODUCED (as an uninitialized-value use with deterministic stock effect). iic_probe() (sys/bus/iicbus/iic.c:115) gates /dev/iicN creation on iicbus_get_addr(), a __BUS_ACCESSOR-generated inline (iicbus.h:56 via sys/sys/bus.h:542-557) that discards BUS_READ_IVARs error and returns its never-written local v. No driver in the iicbus ancestry implements bus_read_ivar and ivars are never allocated (iicbus.c:59-73, 144-146, 164-171); the no-DEFAULT method resolution lands on kobj_error_method (makeobjops.awk:281-282, subr_kobj.c:69-72) which returns ENXIO without touching *result. Stock-kernel proof on the guest: (1) df5558.readivar -- BUS_READ_IVAR error=6 (ENXIO) with sentinel 0x77777777 UNTOUCHED; (2) with stock iicbus.ko+iic.ko the iic child exists but /dev/iic0 is never created -- 240+ device_probe_and_attach re-probes (incl. from zero-sprayed stacks) all ENXIO, because the probe contexts kobj_init/kmalloc path rewrites the slot with garbage > 0 right before DEVICE_PROBE, while the sysctl context returns 0x00000000 -- the value is context-dependent stack residue; (3) the task_log lead is corrected: DragonFlys accessor does NOT deref device_get_ivars, so there is no NULL-deref panic -- the defect is the discarded-failure uninit return. Net stock effect: the production iic(4) interface is dead-on-arrival (also explaining why the pass-1 I2CRDWR findings were never seen in the wild). fix.diff (bus_read_ivar/bus_write_ivar on the iicbus driver, answering 0 for the unallocated addr ivar) validated by rebuilding only iicbus.ko: BUS_READ_IVAR error=0 v=0x0 (written), production iic.ko attaches on the first kldload, /dev/iic0 appears. Direct security impact is contained in-kernel (value is only compared); severity Low.",
  "exploit_chain": "",
  "evidence": "stock-probe-evidence.log (serial console: 240+ attachiic try N: device_probe_and_attach error=6 on stock + the readivar ENXIO/untouched line); dmesg.txt (fixed state: readivar: BUS_READ_IVAR error=0 v=0x0 (written), iic0 attaches); ../DF-5558/run2-full.log (iic0: <I2C generic I/O> on iicbus0 + /dev/iic0 with only iicbus.ko fixed); groom5558.c (proof tool: df5558.readivar / df5558.getaddr_spray / df5558.attachiic).",
  "kernel_refs": [
    "sys/bus/iicbus/iic.c:115",
    "sys/bus/iicbus/iicbus.h:56",
    "sys/bus/iicbus/iicbus.h:44-47",
    "sys/bus/iicbus/iicbus.c:59-73",
    "sys/bus/iicbus/iicbus.c:144-146",
    "sys/bus/iicbus/iicbus.c:164-171",
    "sys/sys/bus.h:542-557",
    "sys/kern/bus_if.m:82-87",
    "sys/tools/makeobjops.awk:281-282",
    "sys/kern/subr_kobj.c:69-72"
  ],
  "poc_changes": "No seed PoC (pass-2 finding verified in the same run). Proof tool is groom5558.ko (sysctl df5558.readivar with a 0x77777777 sentinel; df5558.getaddr_spray two-function stack spray; df5558.attachiic controlled re-probe). The stack-pattern spray did not hit the accessors exact slot (stable zeroed spill in the sysctl context) -- recorded honestly; the ENXIO/untouched dispatch proof plus the stock-vs-fixed probe behavior carry the result.",
  "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": 1800,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df5558 && sh build.sh (builds groom5558.ko with the harness)",
  "run_cmd": "kldload stack per ../DF-5558/run.sh; sysctl df5558.readivar=1; sysctl df5558.attachiic=1",
  "code_hash": "1ba5e7d988c3b6c51fdf0431ad8c316602eb0d42a42af9423d9dc218fcb4449f",
  "notes": "Corrects the iicbb-pass lead (no NULL-ivars deref on DragonFly; the accessor routes through BUS_READ_IVAR). Bucket suggestion: base:hw (family-consistent). The finding also documents why /dev/iicN is effectively dead on stock DragonFly, which suppressed field reports of the iic.c ioctl bugs.",
  "recommended_fix": "Implement bus_read_ivar/bus_write_ivar on the iicbus driver returning a sane default (0) for IICBUS_IVAR_ADDR when no ivars exist (see fix.diff); longer term, allocate iicbus_ivar for children in bus_add_child as FreeBSD does.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff applied to the guests /usr/src copy of sys/bus/iicbus/iicbus.c; only iicbus.ko rebuilt (no kernel rebuild). Baseline stock: BUS_READ_IVAR ENXIO with *result untouched; iic child never attaches (240+ re-probes ENXIO); /dev/iic0 absent. Patched: BUS_READ_IVAR error=0 with *result=0 written; production iic.ko attaches on the first kldload; /dev/iic0 created and fully functional (DF-5558 PoC runs against it).",
  "fix_evidence": "fix.diff; ../DF-5558/fix_build.log (iicbus.ko rebuild); dmesg.txt (readivar: BUS_READ_IVAR error=0 ... v=0x0 (written)); stock-probe-evidence.log (baseline failures)."
}