drivers/message/i2o/i2o_config.c: fix deadlock in compat_ioctl(I2OGETIOPS)
authorAlexey Khoroshilov <khoroshilov@ispras.ru>
Mon, 10 Feb 2014 22:25:35 +0000 (14:25 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 11 Feb 2014 00:01:40 +0000 (16:01 -0800)
i2o_cfg_compat_ioctl(I2OGETIOPS) locks i2o_cfg_mutex and then calls
i2o_cfg_ioctl(I2OGETIOPS) that locks i2o_cfg_mutex as well.  A deadlock
is guaranteed.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/message/i2o/i2o_config.c

index a60c188c2bd937255f60f42920e4b9fbba68cb88..04bd3b6de40188bebf7f083750ed547c38265ec2 100644 (file)
@@ -754,19 +754,19 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
                                 unsigned long arg)
 {
        int ret;
-       mutex_lock(&i2o_cfg_mutex);
        switch (cmd) {
        case I2OGETIOPS:
                ret = i2o_cfg_ioctl(file, cmd, arg);
                break;
        case I2OPASSTHRU32:
+               mutex_lock(&i2o_cfg_mutex);
                ret = i2o_cfg_passthru32(file, cmd, arg);
+               mutex_unlock(&i2o_cfg_mutex);
                break;
        default:
                ret = -ENOIOCTLCMD;
                break;
        }
-       mutex_unlock(&i2o_cfg_mutex);
        return ret;
 }