]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commit
ALSA: seq: Fix possible UAF in snd_seq_check_queue()
authorTakashi Iwai <tiwai@suse.de>
Fri, 9 Mar 2018 20:58:28 +0000 (21:58 +0100)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Wed, 21 Mar 2018 16:40:09 +0000 (13:40 -0300)
commitb429f60411845abc7de5c49c27c35e0eb628fc6a
treee9693e232350e7d4a7a9bc8831cb5e7f966abf77
parent027ac1e780a3dd5fe1fc8a363f997788ed804ad9
ALSA: seq: Fix possible UAF in snd_seq_check_queue()

BugLink: http://bugs.launchpad.net/bugs/1757465
commit d0f833065221cbfcbadf19fd4102bcfa9330006a upstream.

Although we've covered the races between concurrent write() and
ioctl() in the previous patch series, there is still a possible UAF in
the following scenario:

A: user client closed B: timer irq
  -> snd_seq_release()   -> snd_seq_timer_interrupt()
    -> snd_seq_free_client()     -> snd_seq_check_queue()
      -> cell = snd_seq_prioq_cell_peek()
      -> snd_seq_prioq_leave()
         .... removing all cells
      -> snd_seq_pool_done()
         .... vfree()
      -> snd_seq_compare_tick_time(cell)
         ... Oops

So the problem is that a cell is peeked and accessed without any
protection until it's retrieved from the queue again via
snd_seq_prioq_cell_out().

This patch tries to address it, also cleans up the code by a slight
refactoring.  snd_seq_prioq_cell_out() now receives an extra pointer
argument.  When it's non-NULL, the function checks the event timestamp
with the given pointer.  The caller needs to pass the right reference
either to snd_seq_tick or snd_seq_realtime depending on the event
timestamp type.

A good news is that the above change allows us to remove the
snd_seq_prioq_cell_peek(), too, thus the patch actually reduces the
code size.

Reviewed-by: Nicolai Stange <nstange@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
sound/core/seq/seq_prioq.c
sound/core/seq/seq_prioq.h
sound/core/seq/seq_queue.c