[alsa-devel] sound: use-after-free in _snd_timer_stop
Hello,
The following program causes use-after-free in _snd_timer_stop (if run in a parallel loop):
// autogenerated by syzkaller (http://github.com/google/syzkaller) #include <pthread.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <sys/syscall.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
long r[53];
void* thr(void* arg) { switch ((long)arg) { case 0: r[0] = syscall(SYS_mmap, 0x20000000ul, 0x65e000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); break; case 1: r[11] = open("/dev/snd/timer", O_RDWR); break; case 2: *(uint32_t*)0x20653000 = (uint32_t)0x0; *(uint32_t*)0x20653004 = (uint32_t)0x2; *(uint32_t*)0x20653008 = (uint32_t)0x0; *(uint32_t*)0x2065300c = (uint32_t)0x0; *(uint32_t*)0x20653010 = (uint32_t)0x0; *(uint8_t*)0x20653014 = (uint8_t)0x0; *(uint8_t*)0x20653015 = (uint8_t)0x0; *(uint8_t*)0x20653016 = (uint8_t)0x0; *(uint8_t*)0x20653017 = (uint8_t)0x0; *(uint8_t*)0x20653018 = (uint8_t)0x0; *(uint8_t*)0x20653019 = (uint8_t)0x0; *(uint8_t*)0x2065301a = (uint8_t)0x0; *(uint8_t*)0x2065301b = (uint8_t)0x0; *(uint8_t*)0x2065301c = (uint8_t)0x0; *(uint8_t*)0x2065301d = (uint8_t)0x0; *(uint8_t*)0x2065301e = (uint8_t)0x0; *(uint8_t*)0x2065301f = (uint8_t)0x0; *(uint8_t*)0x20653020 = (uint8_t)0x0; *(uint8_t*)0x20653021 = (uint8_t)0x0; *(uint8_t*)0x20653022 = (uint8_t)0x0; *(uint8_t*)0x20653023 = (uint8_t)0x0; *(uint8_t*)0x20653024 = (uint8_t)0x0; *(uint8_t*)0x20653025 = (uint8_t)0x0; *(uint8_t*)0x20653026 = (uint8_t)0x0; *(uint8_t*)0x20653027 = (uint8_t)0x0; *(uint8_t*)0x20653028 = (uint8_t)0x0; *(uint8_t*)0x20653029 = (uint8_t)0x0; *(uint8_t*)0x2065302a = (uint8_t)0x0; *(uint8_t*)0x2065302b = (uint8_t)0x0; *(uint8_t*)0x2065302c = (uint8_t)0x0; *(uint8_t*)0x2065302d = (uint8_t)0x0; *(uint8_t*)0x2065302e = (uint8_t)0x0; *(uint8_t*)0x2065302f = (uint8_t)0x0; *(uint8_t*)0x20653030 = (uint8_t)0x0; *(uint8_t*)0x20653031 = (uint8_t)0x0; *(uint8_t*)0x20653032 = (uint8_t)0x0; *(uint8_t*)0x20653033 = (uint8_t)0x0; r[49] = syscall(SYS_ioctl, r[11], 0x40345410ul, 0x20653000ul, 0, 0, 0); break; case 3: r[50] = syscall(SYS_ioctl, r[11], 0x54a2ul, 0, 0, 0, 0); break; case 4: open("/dev/sequencer", O_RDWR); break; } return 0; }
int main() { long i; pthread_t th[5];
srand(getpid()); memset(r, -1, sizeof(r)); for (i = 0; i < 5; i++) { pthread_create(&th[i], 0, thr, (void*)i); usleep(10000); } for (i = 0; i < 5; i++) { pthread_create(&th[i], 0, thr, (void*)i); if (rand()%2) usleep(rand()%10000); } usleep(100000); return 0; }
BUG: KASAN: use-after-free in snd_timer_notify1+0x42b/0x460 at addr ffff8800331c88b8 Read of size 8 by task a.out/7186 ============================================================================= BUG kmalloc-256 (Tainted: G B W ): kasan: bad access detected -----------------------------------------------------------------------------
INFO: Allocated in snd_timer_instance_new+0x52/0x3a0 age=105 cpu=0 pid=7291 [< none >] ___slab_alloc+0x4c2/0x500 mm/slub.c:2470 [< none >] __slab_alloc+0x66/0xc0 mm/slub.c:2499 [< inline >] slab_alloc_node mm/slub.c:2562 [< inline >] slab_alloc mm/slub.c:2604 [< none >] kmem_cache_alloc_trace+0x27a/0x300 mm/slub.c:2621 [< inline >] kmalloc include/linux/slab.h:463 [< inline >] kzalloc include/linux/slab.h:607 [< none >] snd_timer_instance_new+0x52/0x3a0 sound/core/timer.c:106 [< none >] snd_timer_open+0xbb/0xd20 sound/core/timer.c:251 [< inline >] snd_timer_user_tselect sound/core/timer.c:1572 [< inline >] __snd_timer_user_ioctl sound/core/timer.c:1848 [< none >] snd_timer_user_ioctl+0x8db/0x25f0 sound/core/timer.c:1878 [< inline >] vfs_ioctl fs/ioctl.c:43 [< none >] do_vfs_ioctl+0x18c/0xfb0 fs/ioctl.c:674 [< inline >] SYSC_ioctl fs/ioctl.c:689 [< none >] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:680 [< none >] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 INFO: Freed in snd_timer_close+0x55d/0x750 age=10 cpu=0 pid=7333 [< none >] __slab_free+0x1fc/0x320 mm/slub.c:2680 [< inline >] slab_free mm/slub.c:2835 [< none >] kfree+0x2b7/0x2e0 mm/slub.c:3664 [< none >] snd_timer_close+0x55d/0x750 sound/core/timer.c:375 [< inline >] snd_timer_user_tselect sound/core/timer.c:1562 [< inline >] __snd_timer_user_ioctl sound/core/timer.c:1848 [< none >] snd_timer_user_ioctl+0x7b6/0x25f0 sound/core/timer.c:1878 [< inline >] vfs_ioctl fs/ioctl.c:43 [< none >] do_vfs_ioctl+0x18c/0xfb0 fs/ioctl.c:674 [< inline >] SYSC_ioctl fs/ioctl.c:689 [< none >] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:680 [< none >] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 INFO: Slab 0xffffea0000cc7200 objects=22 used=16 fp=0xffff8800331cbbb8 flags=0x1fffc0000004080 INFO: Object 0xffff8800331c8888 @offset=2184 fp=0xffff8800331c9998 CPU: 2 PID: 7186 Comm: a.out Tainted: G B W 4.5.0-rc1+ #283 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 00000000ffffffff ffff88003372f700 ffffffff8299a06d ffff88003e807000 ffff8800331c8888 ffff8800331c8000 ffff88003372f730 ffffffff81752854 ffff88003e807000 ffffea0000cc7200 ffff8800331c8888 ffff88003372f878 Call Trace: [< inline >] kasan_report mm/kasan/report.c:274 [<ffffffff8175befe>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:295 [<ffffffff84f5ea5b>] snd_timer_notify1+0x42b/0x460 sound/core/timer.c:424 [<ffffffff84f5ed52>] _snd_timer_stop+0x2c2/0x670 sound/core/timer.c:537 [<ffffffff84f5f122>] snd_timer_stop+0x22/0x140 sound/core/timer.c:552 [<ffffffff84fdf617>] snd_seq_timer_close+0x77/0x130 sound/core/seq/seq_timer.c:311 [<ffffffff84fd834e>] queue_delete+0x4e/0xb0 sound/core/seq/seq_queue.c:147 [<ffffffff84fd85bc>] snd_seq_queue_delete+0x3c/0x60 sound/core/seq/seq_queue.c:213 [<ffffffff84fcd84a>] snd_seq_ioctl_delete_queue+0xca/0x120 sound/core/seq/seq_clientmgr.c:1569 [<ffffffff84fcf4ad>] snd_seq_do_ioctl+0x19d/0x1c0 sound/core/seq/seq_clientmgr.c:2209 [<ffffffff84fd0ecb>] snd_seq_kernel_client_ctl+0xdb/0x170 sound/core/seq/seq_clientmgr.c:2423 [<ffffffff84fe7e19>] delete_seq_queue.part.3+0x99/0xf0 sound/core/seq/oss/seq_oss_init.c:389 [< inline >] delete_seq_queue sound/core/seq/oss/seq_oss_init.c:385 [<ffffffff84fe8c3b>] snd_seq_oss_release+0xfb/0x130 sound/core/seq/oss/seq_oss_init.c:434 [<ffffffff84fe724a>] odev_release+0x5a/0x80 sound/core/seq/oss/seq_oss.c:155 [<ffffffff817b2376>] __fput+0x236/0x780 fs/file_table.c:208 [<ffffffff817b2945>] ____fput+0x15/0x20 fs/file_table.c:244 [<ffffffff813ad760>] task_work_run+0x170/0x210 kernel/task_work.c:115 [< inline >] exit_task_work include/linux/task_work.h:21 [<ffffffff81358da5>] do_exit+0x8b5/0x2c60 kernel/exit.c:748 [<ffffffff8135b2c8>] do_group_exit+0x108/0x330 kernel/exit.c:878 [< inline >] SYSC_exit_group kernel/exit.c:889 [<ffffffff8135b50d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:887 [<ffffffff86359636>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 ==================================================================
181.377203] ------------[ cut here ]------------ WARNING: CPU: 1 PID: 29599 at lib/list_debug.c:68 __list_del_entry+0x14c/0x1e0() list_del corruption. prev->next should be ffff88006346f690, but was ffff8800351ebc40 Modules linked in: CPU: 1 PID: 29599 Comm: a.out Not tainted 4.5.0-rc1+ #283 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 00000000ffffffff ffff88003437fa78 ffffffff8299a06d ffff88003437fae8 ffff880034208000 ffffffff866fd220 ffff88003437fab8 ffffffff8134fcf9 ffffffff82a0187c ffffed000686ff59 ffffffff866fd220 0000000000000044 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [<ffffffff8299a06d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50 [<ffffffff8134fcf9>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482 [<ffffffff8134fe09>] warn_slowpath_fmt+0xa9/0xd0 kernel/panic.c:494 [<ffffffff82a0187c>] __list_del_entry+0x14c/0x1e0 lib/list_debug.c:66 [< inline >] list_del_init include/linux/list.h:156 [<ffffffff84f5edf6>] _snd_timer_stop+0x366/0x670 sound/core/timer.c:507 [<ffffffff84f5f122>] snd_timer_stop+0x22/0x140 sound/core/timer.c:552 [<ffffffff84f5f273>] snd_timer_close+0x33/0x750 sound/core/timer.c:322 [<ffffffff84f5fa27>] snd_timer_user_release+0x97/0x130 sound/core/timer.c:1322 [<ffffffff817b2376>] __fput+0x236/0x780 fs/file_table.c:208 [<ffffffff817b2945>] ____fput+0x15/0x20 fs/file_table.c:244 [<ffffffff813ad760>] task_work_run+0x170/0x210 kernel/task_work.c:115 [< inline >] exit_task_work include/linux/task_work.h:21 [<ffffffff81358da5>] do_exit+0x8b5/0x2c60 kernel/exit.c:748 [<ffffffff8135b2c8>] do_group_exit+0x108/0x330 kernel/exit.c:878 [< inline >] SYSC_exit_group kernel/exit.c:889 [<ffffffff8135b50d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:887 [<ffffffff86359636>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 ---[ end trace e005332b84fa3a56 ]--- ==================================================================
Later the machine usually hangs.
On commit 92e963f50fc74041b5e9e744c330dca48e04f08d
participants (1)
-
Dmitry Vyukov