Update of /cvsroot/alsa/alsa-kernel/core/seq/oss
In directory sc8-pr-cvs1:/tmp/cvs-serv14051
Modified Files:
seq_oss_init.c seq_oss_synth.c
Log Message:
Fixed double-free (thus OOPS) problem
Index: seq_oss_init.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/seq/oss/seq_oss_init.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- seq_oss_init.c 5 Mar 2003 11:31:12 -0000 1.9
+++ seq_oss_init.c 11 Mar 2003 20:16:01 -0000 1.10
@@ -51,7 +51,7 @@
static int create_port(seq_oss_devinfo_t *dp);
static int delete_port(seq_oss_devinfo_t *dp);
static int alloc_seq_queue(seq_oss_devinfo_t *dp);
-static int delete_seq_queue(seq_oss_devinfo_t *dp);
+static int delete_seq_queue(int queue);
static void free_devinfo(void *private);
#define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)
@@ -186,6 +186,7 @@
snd_printk(KERN_ERR "can't malloc device info\n");
return -ENOMEM;
}
+ debug_printk(("oss_open: dp = %p\n", dp));
for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) {
if (client_table[i] == NULL)
@@ -215,12 +216,14 @@
}
/* create port */
+ debug_printk(("create new port\n"));
if ((rc = create_port(dp)) < 0) {
snd_printk(KERN_ERR "can't create port\n");
goto _error;
}
/* allocate queue */
+ debug_printk(("allocate queue\n"));
if ((rc = alloc_seq_queue(dp)) < 0)
goto _error;
@@ -236,6 +239,7 @@
dp->file_mode = translate_mode(file);
/* initialize read queue */
+ debug_printk(("initialize read queue\n"));
if (is_read_mode(dp->file_mode)) {
if ((dp->readq = snd_seq_oss_readq_new(dp, maxqlen)) == NULL) {
rc = -ENOMEM;
@@ -244,6 +248,7 @@
}
/* initialize write queue */
+ debug_printk(("initialize write queue\n"));
if (is_write_mode(dp->file_mode)) {
dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen);
if (dp->writeq == NULL) {
@@ -253,11 +258,13 @@
}
/* initialize timer */
+ debug_printk(("initialize timer\n"));
if ((dp->timer = snd_seq_oss_timer_new(dp)) == NULL) {
snd_printk(KERN_ERR "can't alloc timer\n");
rc = -ENOMEM;
goto _error;
}
+ debug_printk(("timer initialized\n"));
/* set private data pointer */
file->private_data = dp;
@@ -275,10 +282,11 @@
return 0;
_error:
- delete_seq_queue(dp);
- delete_port(dp);
snd_seq_oss_synth_cleanup(dp);
snd_seq_oss_midi_cleanup(dp);
+ i = dp->queue;
+ delete_port(dp);
+ delete_seq_queue(i);
return rc;
}
@@ -346,6 +354,7 @@
if (dp->port < 0)
return 0;
+ debug_printk(("delete_port %i\n", dp->port));
memset(&port_info, 0, sizeof(port_info));
port_info.addr.client = dp->cseq;
port_info.addr.port = dp->port;
@@ -377,15 +386,19 @@
* release queue
*/
static int
-delete_seq_queue(seq_oss_devinfo_t *dp)
+delete_seq_queue(int queue)
{
snd_seq_queue_info_t qinfo;
+ int rc;
- if (dp->queue < 0)
+ if (queue < 0)
return 0;
memset(&qinfo, 0, sizeof(qinfo));
- qinfo.queue = dp->queue;
- return call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
+ qinfo.queue = queue;
+ rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
+ if (rc < 0)
+ printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue,
rc);
+ return rc;
}
@@ -416,6 +429,8 @@
void
snd_seq_oss_release(seq_oss_devinfo_t *dp)
{
+ int queue;
+
client_table[dp->index] = NULL;
num_clients--;
@@ -428,10 +443,10 @@
/* clear slot */
debug_printk(("releasing resource..\n"));
+ queue = dp->queue;
if (dp->port >= 0)
delete_port(dp);
- if (dp->queue >= 0)
- delete_seq_queue(dp);
+ delete_seq_queue(queue);
debug_printk(("release done\n"));
}
Index: seq_oss_synth.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/seq/oss/seq_oss_synth.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- seq_oss_synth.c 19 Dec 2002 15:59:18 -0000 1.11
+++ seq_oss_synth.c 11 Mar 2003 20:16:02 -0000 1.12
@@ -302,29 +302,36 @@
seq_oss_synth_t *rec;
seq_oss_synthinfo_t *info;
+ snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return);
for (i = 0; i < dp->max_synthdev; i++) {
info = &dp->synths[i];
if (! info->opened)
continue;
if (info->is_midi) {
- snd_seq_oss_midi_close(dp, info->midi_mapped);
- midi_synth_dev.opened--;
+ if (midi_synth_dev.opened > 0) {
+ snd_seq_oss_midi_close(dp, info->midi_mapped);
+ midi_synth_dev.opened--;
+ }
} else {
rec = get_sdev(i);
if (rec == NULL)
continue;
- if (rec->opened) {
+ if (rec->opened > 0) {
debug_printk(("synth %d closed\n", i));
rec->oper.close(&info->arg);
module_put(rec->oper.owner);
- rec->opened--;
+ rec->opened = 0;
}
snd_use_lock_free(&rec->use_lock);
}
- if (info->sysex)
+ if (info->sysex) {
kfree(info->sysex);
- if (info->ch)
+ info->sysex = NULL;
+ }
+ if (info->ch) {
kfree(info->ch);
+ info->ch = NULL;
+ }
}
dp->synth_opened = 0;
dp->max_synthdev = 0;
@@ -401,15 +408,21 @@
info->sysex->len = 0; /* reset sysex */
reset_channels(info);
if (info->is_midi) {
+ if (midi_synth_dev.opened <= 0)
+ return;
snd_seq_oss_midi_reset(dp, info->midi_mapped);
if (snd_seq_oss_midi_open(dp, info->midi_mapped,
dp->file_mode) < 0) {
midi_synth_dev.opened--;
info->opened = 0;
- if (info->sysex)
+ if (info->sysex) {
kfree(info->sysex);
- if (info->ch)
+ info->sysex = NULL;
+ }
+ if (info->ch) {
kfree(info->ch);
+ info->ch = NULL;
+ }
}
return;
}
-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open!
Get cracking and register here for some mind boggling fun and
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog