⬢ DragonFlyBSD Kernel Audit
DF-4537 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/sound/pci/cs4281.c
+++ b/sys/dev/sound/pci/cs4281.c
@@ -837,18 +837,27 @@
 	goto bad;
     }
 
-    /* create/init mixer */
+    if (pcm_register(dev, sc, 1, 1))
+	goto bad;
+
+    /* create/init mixer -- only after pcm_register() succeeded, so no
+     * failure path can outlive the published 0666 /dev/mixerN */
     codec = AC97_CREATE(dev, sc, cs4281_ac97);
     if (codec == NULL)
-        goto bad;
+	goto bad_unregister;
 
-    mixer_init(dev, ac97_getmixerclass(), codec);
-
-    if (pcm_register(dev, sc, 1, 1))
-	goto bad;
+    if (mixer_init(dev, ac97_getmixerclass(), codec) != 0) {
+	device_printf(dev, "unable to initialize the mixer\n");
+	ac97_destroy(codec);
+	codec = NULL;
+	goto bad_unregister;
+    }
 
-    pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc);
-    pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc);
+    if (pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc) != 0 ||
+	pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc) != 0) {
+	device_printf(dev, "unable to add channels\n");
+	goto bad_unregister;
+    }
 
     ksnprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s",
 	     (sc->regtype == SYS_RES_IOPORT)? "io" : "memory",
@@ -857,6 +866,8 @@
 
     return 0;
 
+ bad_unregister:
+    pcm_unregister(dev);
  bad:
     if (codec)
 	ac97_destroy(codec);