Skip to content

Commit

Permalink
ALSA: seq: Fix potential concurrent access to the deleted pool
Browse files Browse the repository at this point in the history
The input pool of a client might be deleted via the resize ioctl, the
the access to it should be covered by the proper locks.  Currently the
only missing place is the call in snd_seq_ioctl_get_client_pool(), and
this patch papers over it.

Reported-by: syzbot+4a75454b9ca2777f35c7@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Aug 25, 2019
1 parent f9f0e9e commit 7554530
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
3 changes: 1 addition & 2 deletions sound/core/seq/seq_clientmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1835,8 +1835,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
if (cptr->type == USER_CLIENT) {
info->input_pool = cptr->data.user.fifo_pool_size;
info->input_free = info->input_pool;
if (cptr->data.user.fifo)
info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
info->input_free = snd_seq_fifo_unused_cells(cptr->data.user.fifo);
} else {
info->input_pool = 0;
info->input_free = 0;
Expand Down
17 changes: 17 additions & 0 deletions sound/core/seq/seq_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,20 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)

return 0;
}

/* get the number of unused cells safely */
int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f)
{
unsigned long flags;
int cells;

if (!f)
return 0;

snd_use_lock_use(&f->use_lock);
spin_lock_irqsave(&f->lock, flags);
cells = snd_seq_unused_cells(f->pool);
spin_unlock_irqrestore(&f->lock, flags);
snd_use_lock_free(&f->use_lock);
return cells;
}
2 changes: 2 additions & 0 deletions sound/core/seq/seq_fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,7 @@ int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table
/* resize pool in fifo */
int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);

/* get the number of unused cells safely */
int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f);

#endif

0 comments on commit 7554530

Please sign in to comment.