β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-5644

smbus_attach mints NAMELESS wildcard children that any driver on the smbus bus with probe priority above GENERIC can hijack: ipmi_smbus_probe's unconditional BUS_PROBE_DEFAULT claims the generic child and all 96 address children β€” /dev/smbN disappears on non-SSIF platforms and duplicates the SSIF instance on SSIF ones

Summary

The generic and probe children are created nameless so any driver can claim them; the smb driver intentionally probes lowest, requiring every other smbus-bus driver to decline unrelated children - but ipmi_smbus_probe returns BUS_PROBE_DEFAULT unconditionally: with ipmi registered first it claims them all (generic /dev/smbN missing until a later driver-added event on non-SSIF; duplicate ipmi instance on SSIF). Corollary observed live: load-order alone produces two smb devices for one bus. name-the-generic-child + make-ipmi-decline fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5644 Β· 2 files
FileTypeDescriptionSize
README.md file 2.6 KB ↓ raw
verdict.json file 2.3 KB view raw
README.md file
↓ download raw

DF-5644 β€” smbus.c mints NAMELESS wildcard children; any smbus-bus driver with probe priority > GENERIC hijacks them (in-tree: ipmi)

  • File: sys/bus/smbus/smbus.c (pass 2) β€” Severity: Info β€” untested (Phase V not warranted per Low/Info rule; source-proven below)

The defect

smbus_attach creates its children with name = NULL (smbus.c:94, smbus.c:137), and smbus_add_child (smbus.c:143-153) is only reached by drivers that pass an explicit name via BUS_ADD_CHILD (smb.c:108, cyapa.c, atmel_mxt.c, ipmi_smbus.c:59-62). The nameless children are therefore matched against every driver registered on the smbus bus (first_matching_driver, subr_bus.c:1384-1390: no devclass β†’ all drivers), and the winner is decided purely by probe priority (subr_bus.c:1456-1459: higher {SPECIFIC=0 > VENDOR=-10 > DEFAULT=-20

GENERIC=-100} wins).

The bus's own generic I/O driver deliberately probes at the LOWEST priority (smb.c:117, BUS_PROBE_GENERIC), which is only safe if every other driver on the bus declines unrelated children. That etiquette is already violated in-tree: ipmi_smbus_probe (ipmi_smbus.c:66-70) returns BUS_PROBE_DEFAULT unconditionally β€” no unit check, no address check. Whenever the ipmi driver is registered before the wildcard children attach (e.g. device ipmi in the kernel config on an SSIF platform, or kldload ipmi.ko racing boot enumeration):

  • every probe-address child AND the generic child is claimed by ipmi;
  • on non-SSIF platforms ipmi_smbus_attach fails (ipmi_smbus.c:78-84 ENXIO) leaving the children driverless (subr_bus.c:2115-2123 resets state) β€” the generic /dev/smbN never appears until some later driver-added event re-probes them;
  • on SSIF platforms the generic child is attached as a SECOND ipmi instance on the SMBIOS address alongside the identify-created one (ipmi_smbus.c:56-62) β€” two SSIF pollers on one address.

Observed corollary on the audit guest (DF-5642 pack): when smb.ko is registered after smbus0 attached, smb_identify's guarded child takes unit 0 and the line-94 wildcard child is remapped to unit 1 β€” two smb devices for one bus purely from load order.

Fix direction

Give the generic child an explicit name at creation (device_add_child(dev, "smb", device_get_unit(dev))), reserve nameless probing for the address-probe children, and document that convention for future smbus-bus drivers; separately, ipmi_smbus_probe must decline children it did not create (check device_get_unit(dev) & 0x0400 or match its identify child) instead of blanket DEFAULT.

verdict: verdict.json (status: untested β€” Phase V skipped per Low/Info rule).

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

not validated (Info-level; skipped per contract)

n/a
per-fix-DF-5644

Confirmed kernel references

Detail

Evidence (decisive lines)

README.md (path:line chain); DF-5642 pack run logs (smb1 remap corollary); kldstat -v 'smbus/smb' + ipmi_smbus.c probe/identify

PoC changes

n/a (not built)

Verified recommended fix

Create the generic child as device_add_child(dev, "smb", device_get_unit(dev)) and make ipmi_smbus_probe decline non-self-identified children.

Verdict

Source-proven design defect, not runtime-verified (Phase V skipped per Low/Info rule). smbus.c mints NAMELESS wildcard children (smbus.c:94 generic child, smbus.c:137 probe children) that device_probe_child matches against EVERY driver on the smbus bus (subr_bus.c:1384-1390) with priority-based winner selection (subr_bus.c:1456-1459); the bus's generic driver probes at BUS_PROBE_GENERIC (-100, smb.c:117) so ANY driver returning DEFAULT or better claims the wildcard children. In-tree violator: ipmi_smbus_probe returns BUS_PROBE_DEFAULT unconditionally (ipmi_smbus.c:66-70) -- with ipmi registered before the children attach, ipmi hijacks the generic child and all 96 address children; on non-SSIF platforms its attach fails ENXIO (ipmi_smbus.c:78-84) leaving them driverless (/dev/smbN missing), on SSIF platforms it creates a second ipmi instance on the SMBIOS address. Corollary observed live in the DF-5642 runs: late-registered smb.ko + the wildcard child mint two smb devices (smb0 identify child + remapped smb1) for one bus.