• Eric Dumazet's avatar
    net_sched: fix a refcount_t issue with noop_qdisc · 551143d8
    Eric Dumazet authored
    syzkaller reported a refcount_t warning [1]
    
    Issue here is that noop_qdisc refcnt was never really considered as
    a true refcount, since qdisc_destroy() found TCQ_F_BUILTIN set :
    
    if (qdisc->flags & TCQ_F_BUILTIN ||
        !refcount_dec_and_test(&qdisc->refcnt)))
    	return;
    
    Meaning that all atomic_inc() we did on noop_qdisc.refcnt were not
    really needed, but harmless until refcount_t came.
    
    To fix this problem, we simply need to not increment noop_qdisc.refcnt,
    since we never decrement it.
    
    [1]
    refcount_t: increment on 0; use-after-free.
    ------------[ cut here ]------------
    WARNING: CPU: 0 PID: 21754 at lib/refcount.c:152 refcount_inc+0x47/0x50 lib/refcount.c:152
    Kernel panic - not syncing: panic_on_warn set ...
    
    CPU: 0 PID: 21754 Comm: syz-executor7 Not tainted 4.13.0-rc6+ #20
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    Call Trace:
     __dump_stack lib/dump_stack.c:16 [inline]
     dump_stack+0x194/0x257 lib/dump_stack.c:52
     panic+0x1e4/0x417 kernel/panic.c:180
     __warn+0x1c4/0x1d9 kernel/panic.c:541
     report_bug+0x211/0x2d0 lib/bug.c:183
     fixup_bug+0x40/0x90 arch/x86/kernel/traps.c:190
     do_trap_no_signal arch/x86/kernel/traps.c:224 [inline]
     do_trap+0x260/0x390 arch/x86/kernel/traps.c:273
     do_error_trap+0x120/0x390 arch/x86/kernel/traps.c:310
     do_invalid_op+0x1b/0x20 arch/x86/kernel/traps.c:323
     invalid_op+0x1e/0x30 arch/x86/entry/entry_64.S:846
    RIP: 0010:refcount_inc+0x47/0x50 lib/refcount.c:152
    RSP: 0018:ffff8801c43477a0 EFLAGS: 00010282
    RAX: 000000000000002b RBX: ffffffff86093c14 RCX: 0000000000000000
    RDX: 000000000000002b RSI: ffffffff8159314e RDI: ffffed0038868ee8
    RBP: ffff8801c43477a8 R08: 0000000000000001 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff86093ac0
    R13: 0000000000000001 R14: ffff8801d0f3bac0 R15: dffffc0000000000
     attach_default_qdiscs net/sched/sch_generic.c:792 [inline]
     dev_activate+0x7d3/0xaa0 net/sched/sch_generic.c:833
     __dev_open+0x227/0x330 net/core/dev.c:1380
     __dev_change_flags+0x695/0x990 net/core/dev.c:6726
     dev_change_flags+0x88/0x140 net/core/dev.c:6792
     dev_ifsioc+0x5a6/0x930 net/core/dev_ioctl.c:256
     dev_ioctl+0x2bc/0xf90 net/core/dev_ioctl.c:554
     sock_do_ioctl+0x94/0xb0 net/socket.c:968
     sock_ioctl+0x2c2/0x440 net/socket.c:1058
     vfs_ioctl fs/ioctl.c:45 [inline]
     do_vfs_ioctl+0x1b1/0x1520 fs/ioctl.c:685
     SYSC_ioctl fs/ioctl.c:700 [inline]
     SyS_ioctl+0x8f/0xc0 fs/ioctl.c:691
    
    Fixes: 7b936405 ("net, sched: convert Qdisc.refcnt from atomic_t to refcount_t")
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Cc: Reshetova, Elena <elena.reshetova@intel.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    551143d8
sch_generic.h 21.4 KB