diff options
| author | Takashi Iwai <tiwai@suse.de> | 2010-09-06 03:13:45 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2010-09-08 04:45:34 -0400 |
| commit | 27f7ad53829f79e799a253285318bff79ece15bd (patch) | |
| tree | 5b1756cf310d944c5655e07398e77c408e7b4341 | |
| parent | e4ee8dd8afcbcbe502fa8a3d3af6eb09c96dd806 (diff) | |
ALSA: seq/oss - Fix double-free at error path of snd_seq_oss_open()
The error handling in snd_seq_oss_open() has several bad codes that
do dereferecing released pointers and double-free of kmalloc'ed data.
The object dp is release in free_devinfo() that is called via
private_free callback. The rest shouldn't touch this object any more.
The patch changes delete_port() to call kfree() in any case, and gets
rid of unnecessary calls of destructors in snd_seq_oss_open().
Fixes CVE-2010-3080.
Reported-and-tested-by: Tavis Ormandy <taviso@cmpxchg8b.com>
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/core/seq/oss/seq_oss_init.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index 685712276ac9..69cd7b3c362d 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c | |||
| @@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level) | |||
| 281 | return 0; | 281 | return 0; |
| 282 | 282 | ||
| 283 | _error: | 283 | _error: |
| 284 | snd_seq_oss_writeq_delete(dp->writeq); | ||
| 285 | snd_seq_oss_readq_delete(dp->readq); | ||
| 286 | snd_seq_oss_synth_cleanup(dp); | 284 | snd_seq_oss_synth_cleanup(dp); |
| 287 | snd_seq_oss_midi_cleanup(dp); | 285 | snd_seq_oss_midi_cleanup(dp); |
| 288 | delete_port(dp); | ||
| 289 | delete_seq_queue(dp->queue); | 286 | delete_seq_queue(dp->queue); |
| 290 | kfree(dp); | 287 | delete_port(dp); |
| 291 | 288 | ||
| 292 | return rc; | 289 | return rc; |
| 293 | } | 290 | } |
| @@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp) | |||
| 350 | static int | 347 | static int |
| 351 | delete_port(struct seq_oss_devinfo *dp) | 348 | delete_port(struct seq_oss_devinfo *dp) |
| 352 | { | 349 | { |
| 353 | if (dp->port < 0) | 350 | if (dp->port < 0) { |
| 351 | kfree(dp); | ||
| 354 | return 0; | 352 | return 0; |
| 353 | } | ||
| 355 | 354 | ||
| 356 | debug_printk(("delete_port %i\n", dp->port)); | 355 | debug_printk(("delete_port %i\n", dp->port)); |
| 357 | return snd_seq_event_port_detach(dp->cseq, dp->port); | 356 | return snd_seq_event_port_detach(dp->cseq, dp->port); |
