⬢ DragonFlyBSD Kernel Audit
DF-4457 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/sound/pci/cmi.c
+++ b/sys/dev/sound/pci/cmi.c
@@ -983,11 +983,24 @@
 	if (cmi_init(sc))
 		goto bad;
 
-	if (mixer_init(dev, &cmi_mixer_class, sc))
+	if (pcm_register(dev, sc, 1, 1))
 		goto bad;
 
-	if (pcm_register(dev, sc, 1, 1))
+	/*
+	 * mixer_init() publishes a 0666 /dev/mixerN whose devinfo is sc.
+	 * It must run after pcm_register(): were pcm_register() to fail
+	 * after a successful mixer_init(), the bad: unwind below would
+	 * kfree(sc) (and snd_mtxfree(sc->lock)) while /dev/mixerN still
+	 * dispatches open/ioctl into it -- UAF (DF-4457, same family as
+	 * DF-4156/DF-4193/DF-4299/DF-4334/DF-4344/DF-4421).  If mixer_init()
+	 * itself fails, pcm_unregister() tears down the dsp cdevs (and
+	 * calls mixer_uninit()) before bad: frees sc, so no live cdev is
+	 * left dangling over freed memory.
+	 */
+	if (mixer_init(dev, &cmi_mixer_class, sc)) {
+		pcm_unregister(dev);
 		goto bad;
+	}
 
 	cmi_initsys(sc);