mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
ALSA: seq: Fix regression by incorrect ioctl_mutex usages
This is the revised backport of the upstream commitb3defb791bWe had another backport (e.g.623e5c8ae3in 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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7f5cb8e97b
commit
5ff8af891d
@@ -2196,7 +2196,6 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
|
||||
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_seq_client *client, unsigned int cmd,
|
||||
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_seq_client *client, unsigned int cmd,
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user