aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-03-01 12:30:18 -0500
committerTakashi Iwai <tiwai@suse.de>2016-03-01 14:26:40 -0500
commit197b958c1e76a575d77038cc98b4bebc2134279f (patch)
treeffff214617db5a0e674aa44dea139e37cfc980ad
parent17e2df4613be57d0fab68df749f6b8114e453152 (diff)
ALSA: seq: oss: Don't drain at closing a client
The OSS sequencer client tries to drain the pending events at releasing. Unfortunately, as spotted by syzkaller fuzzer, this may lead to an unkillable process state when the event has been queued at the far future. Since the process being released can't be signaled any longer, it remains and waits for the echo-back event in that far future. Back to history, the draining feature was implemented at the time we misinterpreted POSIX definition for blocking file operation. Actually, such a behavior is superfluous at release, and we should just release the device as is instead of keeping it up forever. This patch just removes the draining call that may block the release for too long time unexpectedly. BugLink: http://lkml.kernel.org/r/CACT4Y+Y4kD-aBGj37rf-xBw9bH3GMU6P+MYg4W1e-s-paVD2pg@mail.gmail.com Reported-by: Dmitry Vyukov <dvyukov@google.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/core/seq/oss/seq_oss.c2
-rw-r--r--sound/core/seq/oss/seq_oss_device.h1
-rw-r--r--sound/core/seq/oss/seq_oss_init.c16
3 files changed, 0 insertions, 19 deletions
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 8db156b207f1..8cdf489df80e 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -149,8 +149,6 @@ odev_release(struct inode *inode, struct file *file)
149 if ((dp = file->private_data) == NULL) 149 if ((dp = file->private_data) == NULL)
150 return 0; 150 return 0;
151 151
152 snd_seq_oss_drain_write(dp);
153
154 mutex_lock(&register_mutex); 152 mutex_lock(&register_mutex);
155 snd_seq_oss_release(dp); 153 snd_seq_oss_release(dp);
156 mutex_unlock(&register_mutex); 154 mutex_unlock(&register_mutex);
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index b43924325249..d7b4d016b547 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -127,7 +127,6 @@ int snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int co
127unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait); 127unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
128 128
129void snd_seq_oss_reset(struct seq_oss_devinfo *dp); 129void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
130void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
131 130
132/* */ 131/* */
133void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time); 132void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 6779e82b46dd..92c96a95a903 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -436,22 +436,6 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp)
436 436
437 437
438/* 438/*
439 * Wait until the queue is empty (if we don't have nonblock)
440 */
441void
442snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
443{
444 if (! dp->timer->running)
445 return;
446 if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
447 dp->writeq) {
448 while (snd_seq_oss_writeq_sync(dp->writeq))
449 ;
450 }
451}
452
453
454/*
455 * reset sequencer devices 439 * reset sequencer devices
456 */ 440 */
457void 441void