Patch "ALSA: seq: More protection for concurrent write and ioctl races" has been added to the 3.18-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ALSA: seq: More protection for concurrent write and ioctl races
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
7bd80091567789f1c0cb70eb4737aac8bcd2b6b9Mon Sep 17 00:00:00 2001
From: Takashi Iwai <[email protected]>
Date: Mon, 5 Mar 2018 22:06:09 +0100
Subject: ALSA: seq: More protection for concurrent write and ioctl races
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Takashi Iwai <[email protected]>
commit 7bd80091567789f1c0cb70eb4737aac8bcd2b6b9 upstream.
This patch is an attempt for further hardening against races between the concurrent write and ioctls. The previous fix d15d662e89fc ("ALSA: seq: Fix racy pool initializations") covered the race of the pool initialization at writer and the pool resize ioctl by the client->ioctl_mutex (CVE-2018-1000004). However, basically this mutex should be applied more widely to the whole write operation for avoiding the unexpected pool operations by another thread.
The only change outside snd_seq_write() is the additional mutex argument to helper functions, so that we can unlock / relock the given mutex temporarily during schedule() call for blocking write.
--- sound/core/seq/seq_clientmgr.c | 18 +++++++++++------- sound/core/seq/seq_fifo.c | 2 +- sound/core/seq/seq_memory.c | 14 ++++++++++---- sound/core/seq/seq_memory.h | 3 ++- 4 files changed, 24 insertions(+), 13 deletions(-)
sound/core/seq/seq_clientmgr.c +11 -7
@@ -919,7 +919,8 @@ int snd_seq_dispatch_event(struct snd_sestatic int snd_seq_client_enqueue_event (struct snd_seq_client *client,struct snd_seq_event *event,struct file *file,int blocking, -int atomic,int hop) +int atomic,int hop, +struct mutex *mutexp) {struct snd_seq_event_cell *cell;int err;
@@ -957,7 +958,8 @@ static int snd_seq_client_enqueue_event(return -ENXIO ;/* queue is not allocated */ /* allocate an event cell */ - err =snd_seq_event_dup (client->pool, event, &cell, !blocking || atomic, file); + err =snd_seq_event_dup (client->pool, event, &cell, !blocking || atomic, + file, mutexp);if (err <0 )return err;
@@ -1026,12 +1028,11 @@ static ssize_t snd_seq_write(struct filereturn -ENXIO ;/* allocate the pool now if the pool is not allocated yet */ +mutex_lock (&client->ioctl_mutex);if (client->pool->size >0 && !snd_seq_write_pool_allocated (client)) { -mutex_lock (&client->ioctl_mutex); err =snd_seq_pool_init (client->pool); -mutex_unlock (&client->ioctl_mutex);if (err <0 ) -return -ENOMEM ; + goto out; }/* only process whole events */
@@ -1082,7 +1083,7 @@ static ssize_t snd_seq_write(struct file/* ok, enqueue it */ err =snd_seq_client_enqueue_event (client, &event, file, !(file->f_flags &O_NONBLOCK ), -0 ,0 ); +0 ,0 , &client->ioctl_mutex);if (err <0 )break ;
@@ -1093,6 +1094,8 @@ static ssize_t snd_seq_write(struct file written += len; } + out: +mutex_unlock (&client->ioctl_mutex);return written ? written : err; }
@@ -2355,7 +2358,8 @@ static int kernel_client_enqueue(int cliif (! cptr->accept_output) result = -EPERM ;else /* send it */ - result =snd_seq_client_enqueue_event (cptr, ev, file, blocking, atomic, hop); + result =snd_seq_client_enqueue_event (cptr, ev, file, blocking, + atomic, hop,NULL );snd_seq_client_unlock (cptr);return result;
sound/core/seq/seq_fifo.c +1 -1
@@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seqreturn -EINVAL ;snd_use_lock_use (&f->use_lock); - err =snd_seq_event_dup (f->pool, event, &cell,1 ,NULL );/* always non-blocking */ + err =snd_seq_event_dup (f->pool, event, &cell,1 ,NULL ,NULL );/* always non-blocking */ if (err <0 ) {if ((err == -ENOMEM ) || (err == -EAGAIN ))atomic_inc (&f->overflow);
sound/core/seq/seq_memory.c +10 -4
@@ -221,7 +221,8 @@ void snd_seq_cell_free(struct snd_seq_ev*/ static int snd_seq_cell_alloc (struct snd_seq_pool *pool,struct snd_seq_event_cell **cellp, -int nonblock,struct file *file) +int nonblock,struct file *file, +struct mutex *mutexp) {struct snd_seq_event_cell *cell;unsigned long flags;
@@ -245,7 +246,11 @@ static int snd_seq_cell_alloc(struct sndset_current_state (TASK_INTERRUPTIBLE );add_wait_queue (&pool->output_sleep, &wait);spin_unlock_irq (&pool->lock); +if (mutexp) +mutex_unlock (mutexp);schedule (); +if (mutexp) +mutex_lock (mutexp);spin_lock_irq (&pool->lock);remove_wait_queue (&pool->output_sleep, &wait);/* interrupted? */
@@ -288,7 +293,7 @@ __error:*/ int snd_seq_event_dup (struct snd_seq_pool *pool,struct snd_seq_event *event,struct snd_seq_event_cell **cellp,int nonblock, -struct file *file) +struct file *file,struct mutex *mutexp) {int ncells, err;unsigned int extlen;
@@ -305,7 +310,7 @@ int snd_seq_event_dup(struct snd_seq_pooif (ncells >= pool->total_elements)return -ENOMEM ; - err =snd_seq_cell_alloc (pool, &cell, nonblock, file); + err =snd_seq_cell_alloc (pool, &cell, nonblock, file, mutexp);if (err <0 )return err;
@@ -331,7 +336,8 @@ int snd_seq_event_dup(struct snd_seq_pooint size =sizeof (struct snd_seq_event );if (len < size) size = len; - err =snd_seq_cell_alloc (pool, &tmp, nonblock, file); + err =snd_seq_cell_alloc (pool, &tmp, nonblock, file, + mutexp);if (err <0 ) goto __error;if (cell->event.data.ext.ptr ==NULL )
sound/core/seq/seq_memory.h +2 -1
@@ -66,7 +66,8 @@ struct snd_seq_pool {void snd_seq_cell_free (struct snd_seq_event_cell *cell);int snd_seq_event_dup (struct snd_seq_pool *pool,struct snd_seq_event *event, -struct snd_seq_event_cell **cellp,int nonblock,struct file *file); +struct snd_seq_event_cell **cellp,int nonblock, +struct file *file,struct mutex *mutexp);/* return number of unused (free) cells */ static inline int snd_seq_unused_cells (struct snd_seq_pool *pool)
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/alsa-seq-don-t-allow-resizing-pool-in-use.patch queue-3.18/alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch