3.18-stable review patch.  If anyone has any objections, please let me know.


From: Takashi Iwai <ti...@suse.de>

This is the revised backport of the upstream commit

We had another backport (e.g. 623e5c8ae32b in 4.4.115), but it applies
the new mutex also to the code paths that are invoked via faked
kernel-to-kernel ioctls.  As reported recently, this leads to a
deadlock at suspend (or other scenarios triggering the kernel
sequencer client).

This patch addresses the issue by taking the mutex only in the code
paths invoked by user-space, just like the original fix patch does.

Reported-and-tested-by: Andres Bertens <aberte...@yahoo.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

Tagged as 4.4.x, but should be applied to other older kernels, too.

 sound/core/seq/seq_clientmgr.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -2201,7 +2201,6 @@ static int snd_seq_do_ioctl(struct snd_s
                            void __user *arg)
        struct seq_ioctl_table *p;
-       int ret;
        switch (cmd) {
@@ -2215,12 +2214,8 @@ static int snd_seq_do_ioctl(struct snd_s
        if (! arg)
                return -EFAULT;
        for (p = ioctl_tables; p->cmd; p++) {
-               if (p->cmd == cmd) {
-                       mutex_lock(&client->ioctl_mutex);
-                       ret = p->func(client, arg);
-                       mutex_unlock(&client->ioctl_mutex);
-                       return ret;
-               }
+               if (p->cmd == cmd)
+                       return p->func(client, arg);
        pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
                   cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
@@ -2231,11 +2226,15 @@ static int snd_seq_do_ioctl(struct snd_s
 static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long 
        struct snd_seq_client *client = file->private_data;
+       long ret;
        if (snd_BUG_ON(!client))
                return -ENXIO;
-       return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
+       mutex_lock(&client->ioctl_mutex);
+       ret = snd_seq_do_ioctl(client, cmd, (void __user *) arg);
+       mutex_unlock(&client->ioctl_mutex);
+       return ret;

Reply via email to