DF-4610 / neomagic_probe.c
/* * DF-4610 environment probe — neomagic mixer-UAF (DF-4156 family, 13th). * * The bug: nm_pci_attach() publishes the 0666 /dev/mixerN at mixer_init() * (neomagic.c:695) and keeps two failure paths after it: * * neomagic.c:697-703 IRQ allocation / snd_setup_intr() failure -> goto bad * neomagic.c:709 pcm_register() failure -> goto bad * * bad: (neomagic.c:716-723) then runs * ac97_destroy(codec) <- kobj_delete(methods) + kfree(codec) * kfree(sc) * while the mixer cdev created inside mixer_init() (mixer.c:730-733, * make_dev(..., 0666, "mixer%d"), pdev->si_drv1 = m, m->devinfo = sc) * still dispatches open/ioctl into the freed objects. * * Reproduction on this audit guest is IMPOSSIBLE: it requires a NeoMagic * NM256AV (10c8:8005) / NM256ZX (10c8:8006) PCI audio function whose attach * reaches mixer_init() and then fails at the IRQ/pcm_register step. * QEMU (7.2.22) has no NM256 device model (only AC97/ES1370/HDA/SB16). * * This probe documents that absence and shows the trigger preconditions. */ #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(void) { int i; printf("DF-4610 neomagic mixer-UAF trigger preconditions:\n"); printf(" 1. PCI audio function 10c8:8005 (NM256AV) or 10c8:8006" " (NM256ZX) present\n"); printf(" 2. attach reaches mixer_init() successfully" " (AC97 codec answers)\n"); printf(" 3. bus_alloc_resource_any(IRQ) or snd_setup_intr() fails" " (neomagic.c:697-703),\n" " or pcm_register() fails (neomagic.c:709)\n"); printf(" 4. unprivileged user opens the surviving 0666 /dev/mixerN\n" " -> mixer_ops -> freed snd_mixer/ac97_info/sc\n\n"); printf("This guest: see pciconf output in run.log / env.txt.\n"); for (i = 0; i < 4; i++) { char p[64]; snprintf(p, sizeof(p), "/dev/mixer%d", i); if (access(p, F_OK) == 0) printf("%s exists (belongs to attached pcm driver," " NOT neomagic here)\n", p); } printf("probe done\n"); return 0; } |