linux/net/ipv6
Taehee Yoo aa8caa767e mld: fix suspicious RCU usage in __ipv6_dev_mc_dec()
__ipv6_dev_mc_dec() internally uses sleepable functions so that caller
must not acquire atomic locks. But caller, which is addrconf_verify_rtnl()
acquires rcu_read_lock_bh().
So this warning occurs in the __ipv6_dev_mc_dec().

Test commands:
    ip netns add A
    ip link add veth0 type veth peer name veth1
    ip link set veth1 netns A
    ip link set veth0 up
    ip netns exec A ip link set veth1 up
    ip a a 2001:db8::1/64 dev veth0 valid_lft 2 preferred_lft 1

Splat looks like:
============================
WARNING: suspicious RCU usage
5.12.0-rc6+ #515 Not tainted
-----------------------------
kernel/sched/core.c:8294 Illegal context switch in RCU-bh read-side
critical section!

other info that might help us debug this:

rcu_scheduler_active = 2, debug_locks = 1
4 locks held by kworker/4:0/1997:
 #0: ffff88810bd72d48 ((wq_completion)ipv6_addrconf){+.+.}-{0:0}, at:
process_one_work+0x761/0x1440
 #1: ffff888105c8fe00 ((addr_chk_work).work){+.+.}-{0:0}, at:
process_one_work+0x795/0x1440
 #2: ffffffffb9279fb0 (rtnl_mutex){+.+.}-{3:3}, at:
addrconf_verify_work+0xa/0x20
 #3: ffffffffb8e30860 (rcu_read_lock_bh){....}-{1:2}, at:
addrconf_verify_rtnl+0x23/0xc60

stack backtrace:
CPU: 4 PID: 1997 Comm: kworker/4:0 Not tainted 5.12.0-rc6+ #515
Workqueue: ipv6_addrconf addrconf_verify_work
Call Trace:
 dump_stack+0xa4/0xe5
 ___might_sleep+0x27d/0x2b0
 __mutex_lock+0xc8/0x13f0
 ? lock_downgrade+0x690/0x690
 ? __ipv6_dev_mc_dec+0x49/0x2a0
 ? mark_held_locks+0xb7/0x120
 ? mutex_lock_io_nested+0x1270/0x1270
 ? lockdep_hardirqs_on_prepare+0x12c/0x3e0
 ? _raw_spin_unlock_irqrestore+0x47/0x50
 ? trace_hardirqs_on+0x41/0x120
 ? __wake_up_common_lock+0xc9/0x100
 ? __wake_up_common+0x620/0x620
 ? memset+0x1f/0x40
 ? netlink_broadcast_filtered+0x2c4/0xa70
 ? __ipv6_dev_mc_dec+0x49/0x2a0
 __ipv6_dev_mc_dec+0x49/0x2a0
 ? netlink_broadcast_filtered+0x2f6/0xa70
 addrconf_leave_solict.part.64+0xad/0xf0
 ? addrconf_join_solict.part.63+0xf0/0xf0
 ? nlmsg_notify+0x63/0x1b0
 __ipv6_ifa_notify+0x22c/0x9c0
 ? inet6_fill_ifaddr+0xbe0/0xbe0
 ? lockdep_hardirqs_on_prepare+0x12c/0x3e0
 ? __local_bh_enable_ip+0xa5/0xf0
 ? ipv6_del_addr+0x347/0x870
 ipv6_del_addr+0x3b1/0x870
 ? addrconf_ifdown+0xfe0/0xfe0
 ? rcu_read_lock_any_held.part.27+0x20/0x20
 addrconf_verify_rtnl+0x8a9/0xc60
 addrconf_verify_work+0xf/0x20
 process_one_work+0x84c/0x1440

In order to avoid this problem, it uses rcu_read_unlock_bh() for
a short time. RCU is used for avoiding freeing
ifp(struct *inet6_ifaddr) while ifp is being used. But this will
not be released even if rcu_read_unlock_bh() is used.
Because before rcu_read_unlock_bh(), it uses in6_ifa_hold(ifp).
So this is safe.

Fixes: 63ed8de4be ("mld: add mc_lock for protecting per-interface mld data")
Suggested-by: Eric Dumazet <edumazet@google.com>
Reported-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-04-16 15:40:59 -07:00
..
ila net: Add MODULE_DESCRIPTION entries to network modules 2020-06-20 21:33:57 -07:00
netfilter netfilter: nf_defrag_ipv6: use net_generic infra 2021-04-06 00:34:51 +02:00
addrconf_core.c ipv6: add ipv6_dev_find to stubs 2021-03-30 13:29:39 -07:00
addrconf.c mld: fix suspicious RCU usage in __ipv6_dev_mc_dec() 2021-04-16 15:40:59 -07:00
addrlabel.c ipv6: addrlabel: fix possible memory leak in ip6addrlbl_net_init 2020-11-25 11:20:16 -08:00
af_inet6.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next 2021-04-02 11:03:07 -07:00
ah6.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next 2021-04-14 13:15:12 -07:00
anycast.c ipv6: fix memory leaks on IPV6_ADDRFORM path 2020-07-30 16:30:55 -07:00
calipso.c cipso,calipso: resolve a number of problems with the DOI refcounts 2021-03-04 15:26:57 -08:00
datagram.c lsm,selinux: pass flowi_common instead of flowi to the LSM hooks 2020-11-23 18:36:21 -05:00
esp6_offload.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next 2021-04-14 13:15:12 -07:00
esp6.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next 2021-04-14 13:15:12 -07:00
exthdrs_core.c ipv6: remove printk 2019-07-27 14:23:48 -07:00
exthdrs_offload.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
exthdrs.c seg6: add support for IPv4 decapsulation in ipv6_srh_rcv() 2021-03-11 16:09:21 -08:00
fib6_notifier.c net: fib_notifier: propagate extack down to the notifier block callback 2019-10-04 11:10:56 -07:00
fib6_rules.c fib: use indirect call wrappers in the most common fib_rules_ops 2020-07-28 17:42:31 -07:00
fou6.c net: Add MODULE_DESCRIPTION entries to network modules 2020-06-20 21:33:57 -07:00
icmp.c icmp: ICMPV6: pass RFC 8335 reply messages to ping_rcv 2021-04-13 14:38:01 -07:00
inet6_connection_sock.c lsm,selinux: pass flowi_common instead of flowi to the LSM hooks 2020-11-23 18:36:21 -05:00
inet6_hashtables.c net: ipv6: remove unused arg exact_dif in compute_score 2020-08-31 13:08:10 -07:00
ip6_checksum.c
ip6_fib.c ipv6: fix suspecious RCU usage warning 2021-03-10 12:35:23 -08:00
ip6_flowlabel.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next 2020-08-05 20:13:21 -07:00
ip6_gre.c ipv6: remove extra dev_hold() for fallback tunnels 2021-03-31 14:53:11 -07:00
ip6_icmp.c net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending 2021-02-23 11:29:52 -08:00
ip6_input.c ipv6: weaken the v4mapped source check 2021-03-18 11:19:23 -07:00
ip6_offload.c net/core: move gro function declarations to separate header 2021-02-04 18:37:57 -08:00
ip6_offload.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
ip6_output.c net: use indirect call helpers for dst_output 2021-02-03 14:51:39 -08:00
ip6_tunnel.c ipv6: remove extra dev_hold() for fallback tunnels 2021-03-31 14:53:11 -07:00
ip6_udp_tunnel.c net: Make locking in sock_bindtoindex optional 2020-06-01 14:57:14 -07:00
ip6_vti.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-04-09 20:48:35 -07:00
ip6mr.c net/ipv6: switch ip6_mroute_setsockopt to sockptr_t 2020-07-24 15:41:54 -07:00
ipcomp6.c ipcomp: assign if_id to child tunnel from parent tunnel 2020-07-09 12:55:37 +02:00
ipv6_sockglue.c net/ipv6: propagate user pointer annotation 2020-12-01 11:42:33 -08:00
Kconfig net: ipv6: fix kconfig dependency warning for IPV6_SEG6_HMAC 2020-09-18 17:45:04 -07:00
Makefile net: ipv6: add rpl sr tunnel 2020-03-29 22:30:57 -07:00
mcast_snoop.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 343 2019-06-05 17:37:07 +02:00
mcast.c mld: change lockdep annotation for ip6_sf_socklist and ipv6_mc_socklist 2021-04-05 12:50:04 -07:00
mip6.c xfrm: remove type and offload_type map from xfrm_state_afinfo 2019-06-06 08:34:50 +02:00
ndisc.c net: allow user to set metric on default route learned via Router Advertisement 2021-01-26 18:39:45 -08:00
netfilter.c netfilter: use actual socket sk rather than skb sk when routing harder 2020-10-30 12:57:39 +01:00
output_core.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
ping.c lsm,selinux: pass flowi_common instead of flowi to the LSM hooks 2020-11-23 18:36:21 -05:00
proc.c net: udp: introduce UDP_MIB_MEMERRORS for udp_mem 2020-11-09 15:34:44 -08:00
protocol.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
raw.c net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind() 2021-04-05 12:56:52 -07:00
reassembly.c ipv6: Remove dependency of ipv6_frag_thdr_truncated on ipv6 module 2020-11-19 10:49:50 -08:00
route.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-04-09 20:48:35 -07:00
rpl_iptunnel.c net: ipv6: rpl_iptunnel: simplify the return expression of rpl_do_srh() 2020-12-08 16:22:54 -08:00
rpl.c net: ipv6: rpl*: Fix strange kerneldoc warnings due to bad header 2020-10-30 12:12:52 -07:00
seg6_hmac.c crypto: sha - split sha.h into sha1.h and sha2.h 2020-11-20 14:45:33 +11:00
seg6_iptunnel.c seg6_iptunnel: Refactor seg6_lwt_headroom out of uapi header 2020-08-03 17:57:40 -07:00
seg6_local.c net: seg6: trivial fix of a spelling mistake in comment 2021-04-12 13:17:09 -07:00
seg6.c seg6: fix seg6_validate_srh() to avoid slab-out-of-bounds 2020-06-04 15:39:32 -07:00
sit.c ipv6: remove extra dev_hold() for fallback tunnels 2021-03-31 14:53:11 -07:00
syncookies.c selinux/stable-5.11 PR 20201214 2020-12-16 11:01:04 -08:00
sysctl_net_ipv6.c ipv6: convert elligible sysctls to u8 2021-03-31 14:48:20 -07:00
tcp_ipv6.c mptcp: add mptcp reset option support 2021-04-02 14:21:50 -07:00
tcpv6_offload.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
tunnel6.c tunnel6: add tunnel6_input_afinfo for ipip and ipv6 tunnels 2020-07-09 12:52:37 +02:00
udp_impl.h net: pass a sockptr_t into ->setsockopt 2020-07-24 15:41:54 -07:00
udp_offload.c udp: properly complete L4 GRO over UDP tunnel packet 2021-03-30 17:06:49 -07:00
udp.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next 2021-04-02 11:03:07 -07:00
udplite.c net/ipv6: remove compat_ipv6_{get,set}sockopt 2020-07-19 18:16:41 -07:00
xfrm6_input.c xfrm: state: remove extract_input indirection from xfrm_state_afinfo 2020-05-06 09:40:08 +02:00
xfrm6_output.c xfrm: remove output_finish indirection from xfrm_state_afinfo 2020-05-06 09:40:08 +02:00
xfrm6_policy.c net: add bool confirm_neigh parameter for dst_ops.update_pmtu 2019-12-24 22:28:54 -08:00
xfrm6_protocol.c xfrm: add support for UDPv6 encapsulation of ESP 2020-04-28 11:28:36 +02:00
xfrm6_state.c xfrm: remove output_finish indirection from xfrm_state_afinfo 2020-05-06 09:40:08 +02:00
xfrm6_tunnel.c xfrm: interface: fix the priorities for ipip and ipv6 tunnels 2020-10-09 12:29:48 +02:00