On Sat, 01 Aug 2020 08:24:03 +0200, <qiang.zhang@xxxxxxxxxxxxx> wrote: > > From: Zhang Qiang <qiang.zhang@xxxxxxxxxxxxx> > > There is a potential race window,when a task acquire "src->list_mutex" > write sem,traverse the linked list to find "subs" objects through > parameter "info" in snd_seq_port_disconnect and then release this > write sem, before this task acquire write sem again,this write sem > may be acquired by another task, and get the same "subs" object through > the same "info" before, it could happen "use-after-free" later, so a > simple solution is to delete the object from the linked list when it > is found. > > BUG: KASAN: use-after-free in list_empty include/linux/list.h:282 [inline] > BUG: KASAN: use-after-free in delete_and_unsubscribe_port+0x8b/0x450 > sound/core/seq/seq_ports.c:530 > Read of size 8 at addr ffff888098523060 by task syz-executor.0/7202 > > Call Trace: > __dump_stack lib/dump_stack.c:77 [inline] > dump_stack+0x1f0/0x31e lib/dump_stack.c:118 > print_address_description+0x66/0x5a0 mm/kasan/report.c:383 > __kasan_report mm/kasan/report.c:513 [inline] > kasan_report+0x132/0x1d0 mm/kasan/report.c:530 > list_empty include/linux/list.h:282 [inline] > delete_and_unsubscribe_port+0x8b/0x450 sound/core/seq/seq_ports.c:530 > snd_seq_port_disconnect+0x568/0x610 sound/core/seq/seq_ports.c:612 > snd_seq_ioctl_unsubscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1525 > snd_seq_oss_midi_close+0x397/0x620 sound/core/seq/oss/seq_oss_midi.c:405 > snd_seq_oss_synth_reset+0x335/0x8b0 sound/core/seq/oss/seq_oss_synth.c:406 > snd_seq_oss_reset+0x5b/0x250 sound/core/seq/oss/seq_oss_init.c:435 > snd_seq_oss_ioctl+0x5c2/0x1090 sound/core/seq/oss/seq_oss_ioctl.c:93 > odev_ioctl+0x51/0x70 sound/core/seq/oss/seq_oss.c:174 > vfs_ioctl fs/ioctl.c:48 [inline] > ksys_ioctl fs/ioctl.c:753 [inline] > __do_sys_ioctl fs/ioctl.c:762 [inline] > __se_sys_ioctl+0xf9/0x160 fs/ioctl.c:760 > do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > Allocated by task 7202: > save_stack mm/kasan/common.c:48 [inline] > set_track mm/kasan/common.c:56 [inline] > __kasan_kmalloc+0x103/0x140 mm/kasan/common.c:494 > kmem_cache_alloc_trace+0x234/0x300 mm/slab.c:3551 > kmalloc include/linux/slab.h:555 [inline] > kzalloc include/linux/slab.h:669 [inline] > snd_seq_port_connect+0x66/0x460 sound/core/seq/seq_ports.c:553 > snd_seq_ioctl_subscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1484 > snd_seq_oss_midi_open+0x4db/0x830 sound/core/seq/oss/seq_oss_midi.c:364 > snd_seq_oss_synth_setup_midi+0x108/0x510 sound/core/seq/oss/seq_oss_synth.c:269 > snd_seq_oss_open+0x899/0xe90 sound/core/seq/oss/seq_oss_init.c:261 > odev_open+0x5e/0x90 sound/core/seq/oss/seq_oss.c:125 > chrdev_open+0x498/0x580 fs/char_dev.c:414 > do_dentry_open+0x813/0x1070 fs/open.c:828 > do_open fs/namei.c:3243 [inline] > path_openat+0x278d/0x37f0 fs/namei.c:3360 > do_filp_open+0x191/0x3a0 fs/namei.c:3387 > do_sys_openat2+0x463/0x770 fs/open.c:1179 > do_sys_open fs/open.c:1195 [inline] > __do_sys_openat fs/open.c:1209 [inline] > __se_sys_openat fs/open.c:1204 [inline] > __x64_sys_openat+0x1c8/0x1f0 fs/open.c:1204 > do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > Freed by task 7203: > save_stack mm/kasan/common.c:48 [inline] > set_track mm/kasan/common.c:56 [inline] > kasan_set_free_info mm/kasan/common.c:316 [inline] > __kasan_slab_free+0x114/0x170 mm/kasan/common.c:455 > __cache_free mm/slab.c:3426 [inline] > kfree+0x10a/0x220 mm/slab.c:3757 > snd_seq_port_disconnect+0x570/0x610 sound/core/seq/seq_ports.c:614 > snd_seq_ioctl_unsubscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1525 > snd_seq_oss_midi_close+0x397/0x620 sound/core/seq/oss/seq_oss_midi.c:405 > snd_seq_oss_synth_reset+0x335/0x8b0 sound/core/seq/oss/seq_oss_synth.c:406 > snd_seq_oss_reset+0x5b/0x250 sound/core/seq/oss/seq_oss_init.c:435 > snd_seq_oss_ioctl+0x5c2/0x1090 sound/core/seq/oss/seq_oss_ioctl.c:93 > odev_ioctl+0x51/0x70 sound/core/seq/oss/seq_oss.c:174 > vfs_ioctl fs/ioctl.c:48 [inline] > ksys_ioctl fs/ioctl.c:753 [inline] > __do_sys_ioctl fs/ioctl.c:762 [inline] > __se_sys_ioctl+0xf9/0x160 fs/ioctl.c:760 > do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > The buggy address belongs to the object at ffff888098523000 > which belongs to the cache kmalloc-128 of size 128 > The buggy address is located 96 bytes inside of > 128-byte region [ffff888098523000, ffff888098523080) > The buggy address belongs to the page: > page:ffffea00026148c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 > flags: 0xfffe0000000200(slab) > raw: 00fffe0000000200 ffffea0002613988 ffffea000262c648 ffff8880aa400700 > raw: 0000000000000000 ffff888098523000 0000000100000010 0000000000000000 > page dumped because: kasan: bad access detected > > Memory state around the buggy address: > ffff888098522f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffff888098522f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > >ffff888098523000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ^ > ffff888098523080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffff888098523100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ================================================================== > > Reported-by: syzbot+1a54a94bd32716796edd@xxxxxxxxxxxxxxxxxxxxxxxxx > Signed-off-by: Zhang Qiang <qiang.zhang@xxxxxxxxxxxxx> Thanks for the patch. But I'm afraid that this change would break the existing behavior and might have a bad side-effect. It's likely the same issue as reported in another syzkaller report ("KASAN: invalid-free in snd_seq_port_disconnect"), and Hillf's patch below should covert this as well. Could you check whether it works? thanks, Takashi --- --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -167,11 +167,17 @@ odev_write(struct file *file, const char static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + long rc; struct seq_oss_devinfo *dp; + + mutex_lock(®ister_mutex); dp = file->private_data; if (snd_BUG_ON(!dp)) - return -ENXIO; - return snd_seq_oss_ioctl(dp, cmd, arg); + rc = -ENXIO; + else + rc = snd_seq_oss_ioctl(dp, cmd, arg); + mutex_unlock(®ister_mutex); + return rc; } #ifdef CONFIG_COMPAT