aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai2018-02-19 10:16:01 -0600
committerGreg Kroah-Hartman2018-02-22 08:44:59 -0600
commit5ff8af891df048c57462cabc42bb03a55a42196e (patch)
treef2d8a3147ac289cea17cffdc3410d23392cfdf64
parent7f5cb8e97b42ced7d7c99161825010764aed1946 (diff)
downloadkernel-omap-5ff8af891df048c57462cabc42bb03a55a42196e.tar.gz
kernel-omap-5ff8af891df048c57462cabc42bb03a55a42196e.tar.xz
kernel-omap-5ff8af891df048c57462cabc42bb03a55a42196e.zip
ALSA: seq: Fix regression by incorrect ioctl_mutex usages
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>
-rw-r--r--sound/core/seq/seq_clientmgr.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 7bb9fe7a2c8e..dacc62fe5a58 100644
--- 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_seq_client *client, unsigned int cmd,
2196 void __user *arg) 2196 void __user *arg)
2197{ 2197{
2198 struct seq_ioctl_table *p; 2198 struct seq_ioctl_table *p;
2199 int ret;
2200 2199
2201 switch (cmd) { 2200 switch (cmd) {
2202 case SNDRV_SEQ_IOCTL_PVERSION: 2201 case SNDRV_SEQ_IOCTL_PVERSION:
@@ -2210,12 +2209,8 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
2210 if (! arg) 2209 if (! arg)
2211 return -EFAULT; 2210 return -EFAULT;
2212 for (p = ioctl_tables; p->cmd; p++) { 2211 for (p = ioctl_tables; p->cmd; p++) {
2213 if (p->cmd == cmd) { 2212 if (p->cmd == cmd)
2214 mutex_lock(&client->ioctl_mutex); 2213 return p->func(client, arg);
2215 ret = p->func(client, arg);
2216 mutex_unlock(&client->ioctl_mutex);
2217 return ret;
2218 }
2219 } 2214 }
2220 pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", 2215 pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2221 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2216 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
@@ -2226,11 +2221,15 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
2226static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2221static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2227{ 2222{
2228 struct snd_seq_client *client = file->private_data; 2223 struct snd_seq_client *client = file->private_data;
2224 long ret;
2229 2225
2230 if (snd_BUG_ON(!client)) 2226 if (snd_BUG_ON(!client))
2231 return -ENXIO; 2227 return -ENXIO;
2232 2228
2233 return snd_seq_do_ioctl(client, cmd, (void __user *) arg); 2229 mutex_lock(&client->ioctl_mutex);
2230 ret = snd_seq_do_ioctl(client, cmd, (void __user *) arg);
2231 mutex_unlock(&client->ioctl_mutex);
2232 return ret;
2234} 2233}
2235 2234
2236#ifdef CONFIG_COMPAT 2235#ifdef CONFIG_COMPAT