• Eric Dumazet's avatar
    mISDN: fix a race in dev_expire_timer() · c532eb1d
    Eric Dumazet authored
    commit bdcc5bc25548ef6b08e2e43937148f907c212292 upstream.
    
    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: 's avatarEric Dumazet <edumazet@google.com>
    Cc: Karsten Keil <isdn@linux-pingi.de>
    Reported-by: 's avatarsyzbot <syzkaller@googlegroups.com>
    Signed-off-by: 's avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    c532eb1d
Name
Last commit
Last update
Documentation Loading commit data...
arch Loading commit data...
block Loading commit data...
certs Loading commit data...
crypto Loading commit data...
drivers Loading commit data...
firmware Loading commit data...
fs Loading commit data...
include Loading commit data...
init Loading commit data...
ipc Loading commit data...
kernel Loading commit data...
lib Loading commit data...
mm Loading commit data...
net Loading commit data...
samples Loading commit data...
scripts Loading commit data...
security Loading commit data...
sound Loading commit data...
tools Loading commit data...
usr Loading commit data...
virt Loading commit data...
.get_maintainer.ignore Loading commit data...
.gitignore Loading commit data...
.mailmap Loading commit data...
COPYING Loading commit data...
CREDITS Loading commit data...
Kbuild Loading commit data...
Kconfig Loading commit data...
MAINTAINERS Loading commit data...
Makefile Loading commit data...
README Loading commit data...
REPORTING-BUGS Loading commit data...