⬢ DragonFlyBSD Kernel Audit
DF-2310 / run.log
← back to finding ↓ download raw
DF-2310 stale-heap-to-wire (BUSAUDIT kernel, production iic.ko/iicbus.ko/
iicbb.ko on fakebb3 harness + groom5558.ko; setup patches DF-5559/5560
disclosed; I2CRDWR logic under test STOCK)
====================================================================
# ./poc2310
DF2310: CONTROL (valid buf) slave-rx=404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f
DF2310: groom ran (stats=1)
DF2310: attack I2CRDWR returned SUCCESS despite invalid buf (copyin error swallowed at iic.c:362)
DF2310: ATTACK (invalid buf, post-groom) slave-rx=ffffffffffffffff414c4548454150210100000000000000200000005a5a5a5a

ANALYSIS:
 CONTROL: write msg with a valid buffer -> the emulated slave captures
   exactly the submitted pattern 0x40..0x5f (rig healthy).

 ATTACK: write msg len=32, buf=0xffffffff00000000 (kernel-range ->
   copyin returns EFAULT, silently ignored at iic.c:362 because the
   return value is not checked).  m->buf was kmalloc(32, M_TEMP) WITHOUT
   M_ZERO right after the groom freed a marker-filled chunk of the same
   size class; the wire capture proves stale kernel heap went out on the
   bus:

   ffffffffffffffff  = marker's kernel-realm pointer qword remnant
                       (allocator metadata overwrote the first magic qword)
   414c454845415021  = "ALEHEAP!" -- second half of the groom magic
                       "DF5558STALEHEAP!" (bytes 8..15 of the recycled chunk)
   01000000 ... 5a5a5a5a = marker sequence/size fields + 0x5a fill tail

 At least 12 bytes of provably-stale kernel heap per message were clocked
 out to the I2C peripheral; nothing in the user request contributed them
 (the user buffer was invalid and copyin wrote nothing).  The same root
 user (or anyone physically reading the bus) recovers the bytes: stale
 kernel heap disclosure to an I2C device, per the finding.

 Also note: the ioctl returned SUCCESS -- the swallowed copyin error is
 never reported to userspace.