[ALSA] Fix use after free in opl3_seq and opl3_oss
authorDave Jones <davej@redhat.com>
Mon, 6 Mar 2006 13:03:37 +0000 (14:03 +0100)
committerJaroslav Kysela <perex@suse.cz>
Wed, 22 Mar 2006 09:36:15 +0000 (10:36 +0100)
Modules: OPL3

Don't read from free'd memory.  Also make use of the return
value, and don't register the device if something went wrong
creating the port.

Coverity #954, #955

Signed-off-by: Dave Jones <davej@redhat.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/drivers/opl3/opl3_oss.c
sound/drivers/opl3/opl3_seq.c

index 0345ae6..fccf019 100644 (file)
@@ -104,8 +104,10 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
                                                          voices, voices,
                                                          name);
        if (opl3->oss_chset->port < 0) {
+               int port;
+               port = opl3->oss_chset->port;
                snd_midi_channel_free_set(opl3->oss_chset);
-               return opl3->oss_chset->port;
+               return port;
        }
        return 0;
 }
@@ -136,10 +138,10 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
        arg->oper = oss_callback;
        arg->private_data = opl3;
 
-       snd_opl3_oss_create_port(opl3);
-
-       /* register to OSS synth table */
-       snd_device_register(opl3->card, dev);
+       if (snd_opl3_oss_create_port(opl3)) {
+               /* register to OSS synth table */
+               snd_device_register(opl3->card, dev);
+       }
 }
 
 /* unregister */
index e26556d..57becf3 100644 (file)
@@ -207,8 +207,10 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
                                                      16, voices,
                                                      name);
        if (opl3->chset->port < 0) {
+               int port;
+               port = opl3->chset->port;
                snd_midi_channel_free_set(opl3->chset);
-               return opl3->chset->port;
+               return port;
        }
        return 0;
 }
@@ -218,7 +220,7 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
 static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
 {
        struct snd_opl3 *opl3;
-       int client;
+       int client, err;
        char name[32];
        int opl_ver;
 
@@ -239,7 +241,11 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
        if (client < 0)
                return client;
 
-       snd_opl3_synth_create_port(opl3);
+       if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
+               snd_seq_delete_kernel_client(client);
+               opl3->seq_client = -1;
+               return err;
+       }
 
        /* initialize instrument list */
        opl3->ilist = snd_seq_instr_list_new();