⬢ DragonFlyBSD Kernel Audit
DF-4344 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/sound/pci/atiixp.c	2026-09-19 15:18:11.044552488 +0000
+++ b/sys/dev/sound/pci/atiixp.c	2026-09-19 15:18:33.752261460 +0000
@@ -1004,6 +1004,7 @@
 	struct atiixp_info *sc = (struct atiixp_info *)arg;
 	uint32_t subdev;
 	int i, timeout, found, polling;
+	int mixer_created = 0;
 	char status[SND_STATUSLEN];
 
 	atiixp_lock(sc);
@@ -1083,6 +1084,7 @@
 	}
 
 	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
+	mixer_created = 1;
 
 	if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
 		goto postinitbad;
@@ -1111,6 +1113,16 @@
 	return;
 
 postinitbad:
+	/*
+	 * Failure after mixer_init(): the 0666 /dev/mixerN cdev published
+	 * by mixer_init() (mixer.c:731-733) outlives this driver.  Destroy
+	 * it via mixer_uninit() BEFORE releasing everything it points at:
+	 * mixer_uninit destroys the cdev and, through the AC97 mixer class
+	 * (ac97mix_uninit, ac97.c:1037), destroys the codec itself --
+	 * atiixp_release_resource() must not ac97_destroy() it twice.
+	 */
+	if (mixer_created && mixer_uninit(sc->dev) == 0)
+		sc->codec = NULL;
 	atiixp_release_resource(sc);
 }