⬢ DragonFlyBSD Kernel Audit
DF-4610 / neomagic_probe.c
← back to finding ↓ download raw
/*
 * 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;
}