DF-4334 / via8233_probe.c
/* DF-4334 probe: via_attach() late-failure mixer UAF (attach-error-path family) * * sys/dev/sound/pci/via8233.c calls mixer_init(dev, ac97_getmixerclass(), * via->codec) at line 1335, which make_dev()s a 0666 /dev/mixerN whose * si_drv1->devinfo is the AC97 codec (mixer.c:730-733). If pcm_register() * at via8233.c:1354 then fails (pcm_veto_load != 0 -- initialized to 1 at * sound.c:50 and cleared only on successful feeder init, feeder.c:126 -- * or unit > PCMMAXUNIT=255, sound.c:1027), attach jumps to `bad:' and * ac97_destroy(via->codec) (via8233.c:1372-1373) kobj_delete()s the method * table and kfrees the codec (ac97.c:852-858) while /dev/mixerN still * dispatches ioctls into it -> UAF with indirect-dispatch potential. * * This probe documents why the precondition cannot be created on the audit * guest (and, a fortiori, by an unprivileged user at runtime): * 1. no 1106:3059 PCI audio function exists (host QEMU 7.2.22 predates * the via-ac97 emulation added in QEMU 8.2; `-device help' has no VIA * audio device, so snd_via8233 can never attach here); * 2. pcm_veto_load is cleared at boot by feeder_init and no runtime * interface can set it; * 3. exceeding PCMMAXUNIT=255 requires 256 pcm units, i.e. 256 audio * functions, which this guest cannot provide. */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/param.h> int main(void) { int fd; printf("uname guest: DragonFly 6.5-DEVELOPMENT x86_64 (see env.txt)\n"); /* 1. mixer nodes on this guest (none: no audio function attached) */ fd = open("/dev/mixer0", O_RDWR); if (fd < 0) printf("/dev/mixer0: %s (no audio device attached)\n", strerror(errno)); else { printf("/dev/mixer0 openable\n"); close(fd); } /* * 2. The trigger requires a successfully attached snd_via8233 unit * whose pcm_register() subsequently fails. With the device * absent (checked via pciconf in run.sh) the defect cannot be * instantiated on this guest; with the device present the * failure precondition is a boot-time anomaly (pcm_veto_load / * unit overflow) that an unprivileged user cannot create. */ printf("DF-4334: attach-failure precondition not creatable on this " "guest: no 1106:3059 function, QEMU 7.2.22 has no via-ac97 " "device, pcm_veto_load cleared at boot\n"); return (0); } |