• T
    ALSA: seq: Fix use-after-free at creating a port · 71105998
    Takashi Iwai 提交于
    There is a potential race window opened at creating and deleting a
    port via ioctl, as spotted by fuzzing.  snd_seq_create_port() creates
    a port object and returns its pointer, but it doesn't take the
    refcount, thus it can be deleted immediately by another thread.
    Meanwhile, snd_seq_ioctl_create_port() still calls the function
    snd_seq_system_client_ev_port_start() with the created port object
    that is being deleted, and this triggers use-after-free like:
    
     BUG: KASAN: use-after-free in snd_seq_ioctl_create_port+0x504/0x630 [snd_seq] at addr ffff8801f2241cb1
     =============================================================================
     BUG kmalloc-512 (Tainted: G    B          ): kasan: bad access detected
     -----------------------------------------------------------------------------
     INFO: Allocated in snd_seq_create_port+0x94/0x9b0 [snd_seq] age=1 cpu=3 pid=4511
     	___slab_alloc+0x425/0x460
     	__slab_alloc+0x20/0x40
      	kmem_cache_alloc_trace+0x150/0x190
    	snd_seq_create_port+0x94/0x9b0 [snd_seq]
    	snd_seq_ioctl_create_port+0xd1/0x630 [snd_seq]
     	snd_seq_do_ioctl+0x11c/0x190 [snd_seq]
     	snd_seq_ioctl+0x40/0x80 [snd_seq]
     	do_vfs_ioctl+0x54b/0xda0
     	SyS_ioctl+0x79/0x90
     	entry_SYSCALL_64_fastpath+0x16/0x75
     INFO: Freed in port_delete+0x136/0x1a0 [snd_seq] age=1 cpu=2 pid=4717
     	__slab_free+0x204/0x310
     	kfree+0x15f/0x180
     	port_delete+0x136/0x1a0 [snd_seq]
     	snd_seq_delete_port+0x235/0x350 [snd_seq]
     	snd_seq_ioctl_delete_port+0xc8/0x180 [snd_seq]
     	snd_seq_do_ioctl+0x11c/0x190 [snd_seq]
     	snd_seq_ioctl+0x40/0x80 [snd_seq]
     	do_vfs_ioctl+0x54b/0xda0
     	SyS_ioctl+0x79/0x90
     	entry_SYSCALL_64_fastpath+0x16/0x75
     Call Trace:
      [<ffffffff81b03781>] dump_stack+0x63/0x82
      [<ffffffff81531b3b>] print_trailer+0xfb/0x160
      [<ffffffff81536db4>] object_err+0x34/0x40
      [<ffffffff815392d3>] kasan_report.part.2+0x223/0x520
      [<ffffffffa07aadf4>] ? snd_seq_ioctl_create_port+0x504/0x630 [snd_seq]
      [<ffffffff815395fe>] __asan_report_load1_noabort+0x2e/0x30
      [<ffffffffa07aadf4>] snd_seq_ioctl_create_port+0x504/0x630 [snd_seq]
      [<ffffffffa07aa8f0>] ? snd_seq_ioctl_delete_port+0x180/0x180 [snd_seq]
      [<ffffffff8136be50>] ? taskstats_exit+0xbc0/0xbc0
      [<ffffffffa07abc5c>] snd_seq_do_ioctl+0x11c/0x190 [snd_seq]
      [<ffffffffa07abd10>] snd_seq_ioctl+0x40/0x80 [snd_seq]
      [<ffffffff8136d433>] ? acct_account_cputime+0x63/0x80
      [<ffffffff815b515b>] do_vfs_ioctl+0x54b/0xda0
      .....
    
    We may fix this in a few different ways, and in this patch, it's fixed
    simply by taking the refcount properly at snd_seq_create_port() and
    letting the caller unref the object after use.  Also, there is another
    potential use-after-free by sprintf() call in snd_seq_create_port(),
    and this is moved inside the lock.
    
    This fix covers CVE-2017-15265.
    Reported-and-tested-by: NMichael23 Yu <ycqzsy@gmail.com>
    Suggested-by: NLinus Torvalds <torvalds@linux-foundation.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: NTakashi Iwai <tiwai@suse.de>
    71105998
seq_ports.c 18.7 KB