Revision 4e43e64d0f1332fcc503babad4dc31aead7131ca authored by Eric Dumazet on 28 June 2022, 12:12:48 UTC, committed by Jakub Kicinski on 30 June 2022, 03:41:09 UTC
As reported by syzbot, we should not use rcu_dereference()
when rcu_read_lock() is not held.

WARNING: suspicious RCU usage
5.19.0-rc2-syzkaller #0 Not tainted

net/ipv6/addrconf.c:5175 suspicious rcu_dereference_check() usage!

other info that might help us debug this:

rcu_scheduler_active = 2, debug_locks = 1
1 lock held by syz-executor326/3617:
 #0: ffffffff8d5848e8 (rtnl_mutex){+.+.}-{3:3}, at: netlink_dump+0xae/0xc20 net/netlink/af_netlink.c:2223

stack backtrace:
CPU: 0 PID: 3617 Comm: syz-executor326 Not tainted 5.19.0-rc2-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
 in6_dump_addrs+0x12d1/0x1790 net/ipv6/addrconf.c:5175
 inet6_dump_addr+0x9c1/0xb50 net/ipv6/addrconf.c:5300
 netlink_dump+0x541/0xc20 net/netlink/af_netlink.c:2275
 __netlink_dump_start+0x647/0x900 net/netlink/af_netlink.c:2380
 netlink_dump_start include/linux/netlink.h:245 [inline]
 rtnetlink_rcv_msg+0x73e/0xc90 net/core/rtnetlink.c:6046
 netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2501
 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
 netlink_unicast+0x543/0x7f0 net/netlink/af_netlink.c:1345
 netlink_sendmsg+0x917/0xe10 net/netlink/af_netlink.c:1921
 sock_sendmsg_nosec net/socket.c:714 [inline]
 sock_sendmsg+0xcf/0x120 net/socket.c:734
 ____sys_sendmsg+0x6eb/0x810 net/socket.c:2492
 ___sys_sendmsg+0xf3/0x170 net/socket.c:2546
 __sys_sendmsg net/socket.c:2575 [inline]
 __do_sys_sendmsg net/socket.c:2584 [inline]
 __se_sys_sendmsg net/socket.c:2582 [inline]
 __x64_sys_sendmsg+0x132/0x220 net/socket.c:2582
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x46/0xb0

Fixes: 88e2ca308094 ("mld: convert ifmcaddr6 to RCU")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Link: https://lore.kernel.org/r/20220628121248.858695-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent fa152f6
Raw File
bloat-o-meter
#!/usr/bin/env python3
#
# Copyright 2004 Matt Mackall <mpm@selenic.com>
#
# inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

import sys, os, re
from signal import signal, SIGPIPE, SIG_DFL

signal(SIGPIPE, SIG_DFL)

if len(sys.argv) < 3:
    sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0])
    sys.stderr.write("The options are:\n")
    sys.stderr.write("-c	categorize output based on symbol type\n")
    sys.stderr.write("-d	Show delta of Data Section\n")
    sys.stderr.write("-t	Show delta of text Section\n")
    sys.exit(-1)

re_NUMBER = re.compile(r'\.[0-9]+')

def getsizes(file, format):
    sym = {}
    with os.popen("nm --size-sort " + file) as f:
        for line in f:
            if line.startswith("\n") or ":" in line:
                continue
            size, type, name = line.split()
            if type in format:
                # strip generated symbols
                if name.startswith("__mod_"): continue
                if name.startswith("__se_sys"): continue
                if name.startswith("__se_compat_sys"): continue
                if name.startswith("__addressable_"): continue
                if name == "linux_banner": continue
                if name == "vermagic": continue
                # statics and some other optimizations adds random .NUMBER
                name = re_NUMBER.sub('', name)
                sym[name] = sym.get(name, 0) + int(size, 16)
    return sym

def calc(oldfile, newfile, format):
    old = getsizes(oldfile, format)
    new = getsizes(newfile, format)
    grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
    delta, common = [], {}
    otot, ntot = 0, 0

    for a in old:
        if a in new:
            common[a] = 1

    for name in old:
        otot += old[name]
        if name not in common:
            remove += 1
            down += old[name]
            delta.append((-old[name], name))

    for name in new:
        ntot += new[name]
        if name not in common:
            add += 1
            up += new[name]
            delta.append((new[name], name))

    for name in common:
        d = new.get(name, 0) - old.get(name, 0)
        if d>0: grow, up = grow+1, up+d
        if d<0: shrink, down = shrink+1, down-d
        delta.append((d, name))

    delta.sort()
    delta.reverse()
    return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot

def print_result(symboltype, symbolformat, argc):
    grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \
    calc(sys.argv[argc - 1], sys.argv[argc], symbolformat)

    print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
          (add, remove, grow, shrink, up, -down, up-down))
    print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta"))
    for d, n in delta:
        if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d))

    if otot:
        percent = (ntot - otot) * 100.0 / otot
    else:
        percent = 0
    print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent))

if sys.argv[1] == "-c":
    print_result("Function", "tT", 3)
    print_result("Data", "dDbB", 3)
    print_result("RO Data", "rR", 3)
elif sys.argv[1] == "-d":
    print_result("Data", "dDbBrR", 3)
elif sys.argv[1] == "-t":
    print_result("Function", "tT", 3)
else:
    print_result("Function", "tTdDbBrR", 2)
back to top