| From tiwai@suse.de Mon Feb 19 17:39:59 2018 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Mon, 19 Feb 2018 17:16:01 +0100 |
| Subject: ALSA: seq: Fix regression by incorrect ioctl_mutex usages |
| To: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: Andres Bertens <abertensu@yahoo.com>, ben@decadent.org.uk, stable@vger.kernel.org |
| Message-ID: <20180219161601.24110-1-tiwai@suse.de> |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| This is the revised backport of the upstream commit |
| b3defb791b26ea0683a93a4f49c77ec45ec96f10 |
| |
| 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 <abertensu@yahoo.com> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@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 |
| @@ -2196,7 +2196,6 @@ static int snd_seq_do_ioctl(struct snd_s |
| void __user *arg) |
| { |
| struct seq_ioctl_table *p; |
| - int ret; |
| |
| switch (cmd) { |
| case SNDRV_SEQ_IOCTL_PVERSION: |
| @@ -2210,12 +2209,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)); |
| @@ -2226,11 +2221,15 @@ static int snd_seq_do_ioctl(struct snd_s |
| static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| { |
| 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; |
| } |
| |
| #ifdef CONFIG_COMPAT |