Skip to content
  • Eric Dumazet's avatar
    mISDN: fix a race in dev_expire_timer() · bdcc5bc2
    Eric Dumazet authored
    
    
    Since mISDN_close() uses dev->pending to iterate over active
    timers, there is a chance that one timer got removed from the
    ->pending list in dev_expire_timer() but that the thread
    has not called yet wake_up_interruptible()
    
    So mISDN_close() could miss this and free dev before
    completion of at least one dev_expire_timer()
    
    syzbot was able to catch this race :
    
    BUG: KASAN: use-after-free in register_lock_class+0x140c/0x1bf0 kernel/locking/lockdep.c:827
    Write of size 8 at addr ffff88809fc18948 by task syz-executor1/24769
    
    CPU: 1 PID: 24769 Comm: syz-executor1 Not tainted 5.0.0-rc5 #60
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    Call Trace:
     <IRQ>
     __dump_stack lib/dump_stack.c:77 [inline]
     dump_stack+0x172/0x1f0 lib/dump_stack.c:113
     print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
     kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
     __asan_report_store8_noabort+0x17/0x20 mm/kasan/generic_report.c:140
     register_lock_class+0x140c/0x1bf0 kernel/locking/lockdep.c:827
     __lock_acquire+0x11f/0x4700 kernel/locking/lockdep.c:3224
     lock_acquire+0x16f/0x3f0 kernel/locking/lockdep.c:3841
     __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
     _raw_spin_lock_irqsave+0x95/0xcd kernel/locking/spinlock.c:152
     __wake_up_common_lock+0xc7/0x190 kernel/sched/wait.c:120
     __wake_up+0xe/0x10 kernel/sched/wait.c:145
     dev_expire_timer+0xe4/0x3b0 drivers/isdn/mISDN/timerdev.c:174
     call_timer_fn+0x190/0x720 kernel/time/timer.c:1325
    protocol 88fb is buggy, dev hsr_slave_0
    protocol 88fb is buggy, dev hsr_slave_1
     expire_timers kernel/time/timer.c:1362 [inline]
     __run_timers kernel/time/timer.c:1681 [inline]
     __run_timers kernel/time/timer.c:1649 [inline]
     run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694
     __do_softirq+0x266/0x95a kernel/softirq.c:292
     invoke_softirq kernel/softirq.c:373 [inline]
     irq_exit+0x180/0x1d0 kernel/softirq.c:413
     exiting_irq arch/x86/include/asm/apic.h:536 [inline]
     smp_apic_timer_interrupt+0x14a/0x570 arch/x86/kernel/apic/apic.c:1062
     apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:807
     </IRQ>
    RIP: 0010:__sanitizer_cov_trace_pc+0x26/0x50 kernel/kcov.c:101
    Code: 90 90 90 90 55 48 89 e5 48 8b 75 08 65 48 8b 04 25 40 ee 01 00 65 8b 15 98 12 92 7e 81 e2 00 01 1f 00 75 2b 8b 90 d8 12 00 00 <83> fa 02 75 20 48 8b 88 e0 12 00 00 8b 80 dc 12 00 00 48 8b 11 48
    RSP: 0018:ffff8880589b7a60 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13
    RAX: ffff888087ce25c0 RBX: 0000000000000001 RCX: ffffffff818f8ca3
    RDX: 0000000000000000 RSI: ffffffff818f8b48 RDI: 0000000000000001
    RBP: ffff8880589b7a60 R08: ffff888087ce25c0 R09: ffffed1015d25bd0
    R10: ffffed1015d25bcf R11: ffff8880ae92de7b R12: ffffea0001ae4680
    R13: ffffea0001ae4688 R14: 0000000000000000 R15: ffffea0001b41648
     PageIdle include/linux/page-flags.h:398 [inline]
     page_is_idle include/linux/page_idle.h:29 [inline]
     mark_page_accessed+0x618/0x1140 mm/swap.c:398
     touch_buffer fs/buffer.c:59 [inline]
     __find_get_block+0x312/0xcc0 fs/buffer.c:1298
     sb_find_get_block include/linux/buffer_head.h:338 [inline]
     recently_deleted fs/ext4/ialloc.c:682 [inline]
     find_inode_bit.isra.0+0x202/0x510 fs/ext4/ialloc.c:722
     __ext4_new_inode+0x14ad/0x52c0 fs/ext4/ialloc.c:914
     ext4_symlink+0x3f8/0xbe0 fs/ext4/namei.c:3096
     vfs_symlink fs/namei.c:4126 [inline]
     vfs_symlink+0x378/0x5d0 fs/namei.c:4112
     do_symlinkat+0x22b/0x290 fs/namei.c:4153
     __do_sys_symlink fs/namei.c:4172 [inline]
     __se_sys_symlink fs/namei.c:4170 [inline]
     __x64_sys_symlink+0x59/0x80 fs/namei.c:4170
     do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
     entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457b67
    Code: 0f 1f 00 b8 5c 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 6d bb fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 b8 58 00 00 00 0f 05 <48> 3d 01 f0 ff ff 0f 83 4d bb fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fff045ce0f8 EFLAGS: 00000202 ORIG_RAX: 0000000000000058
    RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 0000000000457b67
    RDX: 00007fff045ce173 RSI: 00000000004bd63f RDI: 00007fff045ce160
    RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000013
    R10: 0000000000000075 R11: 0000000000000202 R12: 0000000000000000
    R13: 0000000000000001 R14: 000000000000029b R15: 0000000000000001
    
    Allocated by task 24763:
     save_stack+0x45/0xd0 mm/kasan/common.c:73
     set_track mm/kasan/common.c:85 [inline]
     __kasan_kmalloc mm/kasan/common.c:496 [inline]
     __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:469
     kasan_kmalloc+0x9/0x10 mm/kasan/common.c:504
     kmem_cache_alloc_trace+0x151/0x760 mm/slab.c:3609
     kmalloc include/linux/slab.h:545 [inline]
     mISDN_open+0x9a/0x270 drivers/isdn/mISDN/timerdev.c:59
     misc_open+0x398/0x4c0 drivers/char/misc.c:141
     chrdev_open+0x247/0x6b0 fs/char_dev.c:417
     do_dentry_open+0x47d/0x1130 fs/open.c:771
     vfs_open+0xa0/0xd0 fs/open.c:880
     do_last fs/namei.c:3418 [inline]
     path_openat+0x10d7/0x4690 fs/namei.c:3534
     do_filp_open+0x1a1/0x280 fs/namei.c:3564
     do_sys_open+0x3fe/0x5d0 fs/open.c:1063
     __do_sys_openat fs/open.c:1090 [inline]
     __se_sys_openat fs/open.c:1084 [inline]
     __x64_sys_openat+0x9d/0x100 fs/open.c:1084
     do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
     entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    Freed by task 24762:
     save_stack+0x45/0xd0 mm/kasan/common.c:73
     set_track mm/kasan/common.c:85 [inline]
     __kasan_slab_free+0x102/0x150 mm/kasan/common.c:458
     kasan_slab_free+0xe/0x10 mm/kasan/common.c:466
     __cache_free mm/slab.c:3487 [inline]
     kfree+0xcf/0x230 mm/slab.c:3806
     mISDN_close+0x2a1/0x390 drivers/isdn/mISDN/timerdev.c:97
     __fput+0x2df/0x8d0 fs/file_table.c:278
     ____fput+0x16/0x20 fs/file_table.c:309
     task_work_run+0x14a/0x1c0 kernel/task_work.c:113
     tracehook_notify_resume include/linux/tracehook.h:188 [inline]
     exit_to_usermode_loop+0x273/0x2c0 arch/x86/entry/common.c:166
     prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
     syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
     do_syscall_64+0x52d/0x610 arch/x86/entry/common.c:293
     entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    The buggy address belongs to the object at ffff88809fc18900
     which belongs to the cache kmalloc-192 of size 192
    The buggy address is located 72 bytes inside of
     192-byte region [ffff88809fc18900, ffff88809fc189c0)
    The buggy address belongs to the page:
    page:ffffea00027f0600 count:1 mapcount:0 mapping:ffff88812c3f0040 index:0xffff88809fc18000
    flags: 0x1fffc0000000200(slab)
    raw: 01fffc0000000200 ffffea000269f648 ffffea00029f7408 ffff88812c3f0040
    raw: ffff88809fc18000 ffff88809fc18000 000000010000000b 0000000000000000
    page dumped because: kasan: bad access detected
    
    Memory state around the buggy address:
     ffff88809fc18800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     ffff88809fc18880: 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    >ffff88809fc18900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                                  ^
     ffff88809fc18980: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
     ffff88809fc18a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Cc: Karsten Keil <isdn@linux-pingi.de>
    Reported-by: default avatarsyzbot <syzkaller@googlegroups.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    bdcc5bc2