]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - sound/oss/soundcard.c
OSS: soundcard: locking bug in sound_ioctl()
[net-next-2.6.git] / sound / oss / soundcard.c
index 2d9c51312622fe4a10ea0bf202f24fb092a895ac..07f803e6d203a41615db0923cf073f7eadc283b6 100644 (file)
@@ -210,42 +210,44 @@ static int sound_open(struct inode *inode, struct file *file)
                printk(KERN_ERR "Invalid minor device %d\n", dev);
                return -ENXIO;
        }
+       lock_kernel();
        switch (dev & 0x0f) {
        case SND_DEV_CTL:
                dev >>= 4;
                if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
                        request_module("mixer%d", dev);
                }
+               retval = -ENXIO;
                if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
-                       return -ENXIO;
+                       break;
        
                if (!try_module_get(mixer_devs[dev]->owner))
-                       return -ENXIO;
+                       break;
+
+               retval = 0;
                break;
 
        case SND_DEV_SEQ:
        case SND_DEV_SEQ2:
-               if ((retval = sequencer_open(dev, file)) < 0)
-                       return retval;
+               retval = sequencer_open(dev, file);
                break;
 
        case SND_DEV_MIDIN:
-               if ((retval = MIDIbuf_open(dev, file)) < 0)
-                       return retval;
+               retval = MIDIbuf_open(dev, file);
                break;
 
        case SND_DEV_DSP:
        case SND_DEV_DSP16:
        case SND_DEV_AUDIO:
-               if ((retval = audio_open(dev, file)) < 0)
-                       return retval;
+               retval = audio_open(dev, file);
                break;
 
        default:
                printk(KERN_ERR "Invalid minor device %d\n", dev);
-               return -ENXIO;
+               retval = -ENXIO;
        }
 
+       unlock_kernel();
        return 0;
 }
 
@@ -389,11 +391,11 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case SND_DEV_DSP:
        case SND_DEV_DSP16:
        case SND_DEV_AUDIO:
-               return audio_ioctl(dev, file, cmd, p);
+               ret = audio_ioctl(dev, file, cmd, p);
                break;
 
        case SND_DEV_MIDIN:
-               return MIDIbuf_ioctl(dev, file, cmd, p);
+               ret = MIDIbuf_ioctl(dev, file, cmd, p);
                break;
 
        }