⬢ DragonFlyBSD Kernel Audit
DF-5637 / run_baseline.log
← back to finding ↓ download raw
DF-5636/5637/5638 BASELINE RUN -- unmodified production code
Guest: DragonFly 6.5-DEVELOPMENT #0 (image kernel, Jul  2 2026) -- smbus
compiled into X86_64_GENERIC (config line 335), iicbus/iicbb/iicsmb loaded
from unmodified /boot/kernel/*.ko.  Chain: fakebb0 -> iicbb0 -> iicbus0 ->
iicsmb0 -> smbus0.  Wire sanity round trip passes before every test.

$ kldload iicbus.ko iicbb.ko iicbb_reg.ko df5636_rig.ko iicsmb.ko
fakebb0: <DF-5636 fake GPIO bit-bang i2c master+slave> on motherboard
iicbb0: <I2C bit-banging driver> on fakebb0
iicbus0: <Philips I2C bus> on iicbb0 addr 0x0
[df5636] attach done: iicbus=0xfffff801175bbb60 cdev=0xfffff8008da31c80 busy=0 (now: kldload iicsmb)
[df5636] sanity iicbus_request_bus error=0
[df5636] SANITY: write_ok=1 read_ok=1 starts=2 stops=2
iicsmb0: <SMBus over I2C bridge> on iicbus0
smbus0: <System Management Bus> on iicsmb0

================ F1: wake-path phantom grant (DF-5636) ================
$ ./df5636ctl f1          -> summary=0x3 (phantom grant + double grant)
[df5636] F1.1 request(devA=fakebb0)=0 owner=0xfffff801175bbca0
[df5636] T(devB): calling smbus_request_bus(iicbb0, how=0x3) softc=0xfffff8008d561050
[df5636] F1.2 owner while devB parked=0xfffff801175bbca0 (devA=0xfffff801175bbca0 devB=0xfffff801175ff080)
[df5636] F1.3 release(devA)=0 owner=0
[df5636] T(devB): request RETURNED 0
[df5636] T(devB): sc->owner=0 (caller=0xfffff801175ff080)  <<< PHANTOM GRANT: success returned, owner is NOT the caller
[df5636] F1.3w 000ms after release: owner=0 t1.done=1
[df5636] T(devC): calling smbus_request_bus(iicbus0, how=0x3) softc=0xfffff8008d561050
[df5636] T(devC): request RETURNED 0
[df5636] T(devC): sc->owner=0xfffff801175fefe0 (caller=0xfffff801175fefe0)
[df5636] F1.4 after 1s of devC request: owner=0xfffff801175fefe0 devC.done=1 (1 = granted immediately)
[df5636] F1.5 release(devB)=13
[df5636] F1.5b cleanup release(devC)=0 owner=0
[df5636] F1.6 final owner=0 (clean=NULL) t1.done=1 t2.done=1

  ==> devB was woken by the release and returned SUCCESS (0) without
      sc->owner ever being set to it; devC then also granted => two
      concurrent callers both believe they hold the bus (DOUBLE GRANT).
      F1.5: devB's own release() = EACCES(13) AND (observed live in the
      first baseline session) it tore down the iicbus under devC.

================ F2: SMB_DONTWAIT phantom grant (DF-5636) ==============
(from the first baseline session; owner was left = devC by F1's wedge,
 which is itself DF-5637's teardown consequence -- the F2 lines show the
 DONTWAIT leg on a bus verifiably owned by ANOTHER device)
[df5636] F2.1 request(devA)=-1 owner=0xfffff801175bbb60
[df5636] F2.2 request(devB, SMB_DONTWAIT)=0 owner=0xfffff801175bbb60 caller=0xfffff801175bbc00 <<< PHANTOM GRANT (must be EWOULDBLOCK)
[df5636] F2.3 cleanup release(devA)=13 owner=0xfffff801175bbb60

================ F3: non-owner release teardown (DF-5637) ==============
$ ./df5636ctl f3           -> summary=0x1
[df5636] F3.1 request(devA)=0 owner=0xfffff801175bbca0 (iicbus now held via iicsmb)
[df5636] F3.2 NON-owner release(devB)=13 smbus owner still=0xfffff801175bbca0
[df5636] F3.3 iicbus probe request(devC, DONTWAIT)=0 <<< iicbus TORN DOWN by the non-owner release while devA owns smbus
[df5636] F3.4 cleanup release(devA)=0 owner=0

  ==> A device that does NOT own the smbus had its release() answered
      EACCES at the smbus level, but the underlying iicbus exclusion was
      ALREADY released (probe granted) while the real owner devA was
      still mid-ownership.

================ F3B: EACCES release wakes waiter into grant ===========
$ ./df5636ctl f3b          -> summary=0x1
[df5636] F3B.1 request(devA)=0 owner=0xfffff801175bbca0
[df5636] T(devB): calling smbus_request_bus(iicbb0, how=0x3) softc=0xfffff8008d561050
[df5636] F3B.2 owner while devB parked=0xfffff801175bbca0 (devA=0xfffff801175bbca0)
[df5636] F3B.3 NON-owner release(devC)=13 owner STILL=0xfffff801175bbca0
[df5636] F3B.3w t1 verdict: error=0 owner_seen=0xfffff801175bbca0 (devA=0xfffff801175bbca0)  <<< GRANTED while another device verifiably OWNS the bus (no release ever happened)

  ==> smbconf.c:177's unconditional wakeup(sc) on the EACCES path woke
      the parked requester; the broken loop turned it into a success
      return WHILE devA STILL OWNS the bus.  No release happened at all.

================ F5/PARK: unkillable smbreq park (DF-5638) =============
$ ./df5636ctl park &       (PARK holds devA, then parks caller on request(devB, SMB_WAIT=0x1))
$ ps -o pid,stat,wchan,command -p $P
  PID STAT WCHAN  COMMAND
 1742 D4    smbreq ./df5636ctl park          <-- D state, non-PCATCH tsleep
$ kill -9 1742; sleep 1
$ ps -o pid,stat,wchan -p 1742
 1742 D4    smbreq                            <-- SURVIVES kill -9
$ ./df5636ctl unpark
[df5636] PARK: holding bus with devA=0xfffff801175bbca0, parking caller on request(devB, SMB_WAIT=0x1)
[df5636] UNPARK: release(devA)=0
[df5636] PARK: woke: request(devB) returned 0 owner=0 caller=0xfffff8008bb64320  <<< phantom grant on wake

  ==> The user process sat UNKILLABLE (D state, kill -9 ineffective) in
      tsleep(sc, 0, "smbreq", 0) -- smbconf.c:92-94 via SMB_WAIT (0x1).
      The pending SIGKILL was only delivered after the unwedge, and the
      wake path handed it a phantom grant.