rtnetlink: use rcu_dereference_raw to silence rcu splat
authorFlorian Westphal <fw@strlen.de>
Thu, 10 Aug 2017 14:52:57 +0000 (16:52 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 Aug 2017 16:50:21 +0000 (09:50 -0700)
Ido reports a rcu splat in __rtnl_register.
The splat is correct; as rtnl_register doesn't grab any logs
and doesn't use rcu locks either.  It has always been like this.
handler families are not registered in parallel so there are no
races wrt. the kmalloc ordering.

The only reason to use rcu_dereference in the first place was to
avoid sparse from complaining about this.

Thus this switches to _raw() to not have rcu checks here.

The alternative is to add rtnl locking to register/unregister,
however, I don't see a compelling reason to do so as this has been
lockless for the past twenty years or so.

Fixes: 6853dd4881 ("rtnetlink: protect handler table with rcu")
Reported-by: Ido Schimmel <idosch@idosch.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Tested-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/rtnetlink.c

index dd4e50dfa248f82ce3d3638d41c92ff134dff1f7..a5bc5bd0dc1289d52e0b8158e640c2ff406060e2 100644 (file)
@@ -172,7 +172,7 @@ int __rtnl_register(int protocol, int msgtype,
        BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
        msgindex = rtm_msgindex(msgtype);
 
-       tab = rcu_dereference(rtnl_msg_handlers[protocol]);
+       tab = rcu_dereference_raw(rtnl_msg_handlers[protocol]);
        if (tab == NULL) {
                tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL);
                if (tab == NULL)