Commit 5e315e9248329c53a8932b71532c28240125e3c4

Authored by Dave Jones
Committed by Jaroslav Kysela
1 parent 3de4414e79

[ALSA] Fix use after free in opl3_seq and opl3_oss

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>

Showing 2 changed files with 16 additions and 8 deletions Side-by-side Diff

sound/drivers/opl3/opl3_oss.c
... ... @@ -104,8 +104,10 @@
104 104 voices, voices,
105 105 name);
106 106 if (opl3->oss_chset->port < 0) {
  107 + int port;
  108 + port = opl3->oss_chset->port;
107 109 snd_midi_channel_free_set(opl3->oss_chset);
108   - return opl3->oss_chset->port;
  110 + return port;
109 111 }
110 112 return 0;
111 113 }
... ... @@ -136,10 +138,10 @@
136 138 arg->oper = oss_callback;
137 139 arg->private_data = opl3;
138 140  
139   - snd_opl3_oss_create_port(opl3);
140   -
141   - /* register to OSS synth table */
142   - snd_device_register(opl3->card, dev);
  141 + if (snd_opl3_oss_create_port(opl3)) {
  142 + /* register to OSS synth table */
  143 + snd_device_register(opl3->card, dev);
  144 + }
143 145 }
144 146  
145 147 /* unregister */
sound/drivers/opl3/opl3_seq.c
... ... @@ -207,8 +207,10 @@
207 207 16, voices,
208 208 name);
209 209 if (opl3->chset->port < 0) {
  210 + int port;
  211 + port = opl3->chset->port;
210 212 snd_midi_channel_free_set(opl3->chset);
211   - return opl3->chset->port;
  213 + return port;
212 214 }
213 215 return 0;
214 216 }
... ... @@ -218,7 +220,7 @@
218 220 static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
219 221 {
220 222 struct snd_opl3 *opl3;
221   - int client;
  223 + int client, err;
222 224 char name[32];
223 225 int opl_ver;
224 226  
... ... @@ -239,7 +241,11 @@
239 241 if (client < 0)
240 242 return client;
241 243  
242   - snd_opl3_synth_create_port(opl3);
  244 + if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
  245 + snd_seq_delete_kernel_client(client);
  246 + opl3->seq_client = -1;
  247 + return err;
  248 + }
243 249  
244 250 /* initialize instrument list */
245 251 opl3->ilist = snd_seq_instr_list_new();