/*
 * DF-4983 — cxm(4): cxm_iic_detach()'s iicbus invalidation is a
 * permanent no-op -> struct cxm_softc.iicbus dangles after iic teardown
 *
 * Root cause (two halves):
 *
 *  sys/dev/video/cxm/cxm_i2c.c:229  (cxm_iic_detach)
 *      BUS_WRITE_IVAR(device_get_parent(dev), dev,
 *                     CXM_IVAR_IICBUS, 0);          // return IGNORED
 *
 *  sys/dev/video/cxm/cxm.c:2115-2118 (cxm_write_ivar)
 *      case CXM_IVAR_IICBUS:
 *          if (sc->iicbus)          // always TRUE at detach time —
 *              return EINVAL;       // the clear is rejected FOREVER
 *          sc->iicbus = val ? *(device_t *)val : NULL;
 *
 * cxm_iic_attach() is the only setter (via the same ivar), so whenever
 * cxm_iic_detach() runs, sc->iicbus != NULL and the write returns EINVAL
 * before reaching the assignment. The ignored return makes the one line
 * of lifetime cleanup in this driver dead code: after the iicbus/iicbb
 * grandchildren are destroyed, cxm_softc.iicbus still points at the
 * destroyed device_t.
 *
 * Consumers that dereference the stale pointer (all take sc and use
 * sc->iicbus directly -> iicbus_start/write/read/stop on it):
 *   cxm_saa7115.c:678,685,689,... (27 uses)
 *   cxm_msp34xxx.c:295,298,302,338,365,...
 *   cxm_tuner.c / cxm_eeprom.c (same pattern)
 *
 * Reachability of a dereference after invalidation: any cxm ioctl that
 * touches the I2C sensors racing cxm_detach() (kldunload cxm). cxm has
 * zero serialization on that path — this is the same detach-vs-ioctl
 * race already filed as DF-4753 (cxm_msp twin) / DF-4419 family; the
 * new fact here is the second freed object (the iicbus device_t itself)
 * that the glue layer *intended* to invalidate and cannot.
 *
 * Non-racy paths are safe today: cxm.c:622 guards stop_hardware's I2C
 * calls with `if (sc->cxm_iic)`, and that sibling pointer IS nulled
 * (cxm_child_detached, cxm.c:2066-2067). Only the ivar-cleared iicbus
 * pointer is left stale — the invalidation asymmetry is the defect.
 *
 * HARDWARE GATE (why untested): cxm_iic only attaches as a child of a
 * cxm(4) device, which only probes on a Conexant iTVC15/iTVC16 MPEG
 * codec card (Hauppauge PVR-250/350, PCI vendor 0x4444). The reference
 * QEMU guest has none (verified: cxm.ko resident, /dev/cxm never
 * created). This "PoC" therefore documents the trigger; running it
 * needs the card.
 *
 * Sketch of the live trigger on equipped hardware (root + unpriv user):
 *   user$:   while :; do dd if=/dev/cxm0 of=/dev/null bs=64k count=1; done
 *            (or loop a sensor ioctl: CXM_IOCTG_SOURCE / SELECT etc.)
 *   root#:   kldunload cxm_iic cxm    # or just kldunload cxm
 *   -> cxm_detach -> bus_generic_detach -> cxm_iic_detach (no-op clear)
 *      -> device_delete_child frees iicbus/iicbb devices
 *      -> in-flight ioctl in cxm_saa7115_* / cxm_msp_* calls
 *         iicbus_start(freed device_t)  => UAF on iicbus device
 *
 * Fix (fix.diff in this pack): give write_ivar an explicit detach-mode —
 * val == 0 clears unconditionally; non-zero keeps the set-once guard.
 */
