linux/net/ipv6
Nikolay Aleksandrov 0406c74e0c ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route
commit 2cf750704b upstream.

Since the commit below the ipmr/ip6mr rtnl_unicast() code uses the portid
instead of the previous dst_pid which was copied from in_skb's portid.
Since the skb is new the portid is 0 at that point so the packets are sent
to the kernel and we get scheduling while atomic or a deadlock (depending
on where it happens) by trying to acquire rtnl two times.
Also since this is RTM_GETROUTE, it can be triggered by a normal user.

Here's the sleeping while atomic trace:
[ 7858.212557] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620
[ 7858.212748] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
[ 7858.212881] 2 locks held by swapper/0/0:
[ 7858.213013]  #0:  (((&mrt->ipmr_expire_timer))){+.-...}, at: [<ffffffff810fbbf5>] call_timer_fn+0x5/0x350
[ 7858.213422]  #1:  (mfc_unres_lock){+.....}, at: [<ffffffff8161e005>] ipmr_expire_process+0x25/0x130
[ 7858.213807] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.0-rc7+ #179
[ 7858.213934] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
[ 7858.214108]  0000000000000000 ffff88005b403c50 ffffffff813a7804 0000000000000000
[ 7858.214412]  ffffffff81a1338e ffff88005b403c78 ffffffff810a4a72 ffffffff81a1338e
[ 7858.214716]  000000000000026c 0000000000000000 ffff88005b403ca8 ffffffff810a4b9f
[ 7858.215251] Call Trace:
[ 7858.215412]  <IRQ>  [<ffffffff813a7804>] dump_stack+0x85/0xc1
[ 7858.215662]  [<ffffffff810a4a72>] ___might_sleep+0x192/0x250
[ 7858.215868]  [<ffffffff810a4b9f>] __might_sleep+0x6f/0x100
[ 7858.216072]  [<ffffffff8165bea3>] mutex_lock_nested+0x33/0x4d0
[ 7858.216279]  [<ffffffff815a7a5f>] ? netlink_lookup+0x25f/0x460
[ 7858.216487]  [<ffffffff8157474b>] rtnetlink_rcv+0x1b/0x40
[ 7858.216687]  [<ffffffff815a9a0c>] netlink_unicast+0x19c/0x260
[ 7858.216900]  [<ffffffff81573c70>] rtnl_unicast+0x20/0x30
[ 7858.217128]  [<ffffffff8161cd39>] ipmr_destroy_unres+0xa9/0xf0
[ 7858.217351]  [<ffffffff8161e06f>] ipmr_expire_process+0x8f/0x130
[ 7858.217581]  [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.217785]  [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.217990]  [<ffffffff810fbc95>] call_timer_fn+0xa5/0x350
[ 7858.218192]  [<ffffffff810fbbf5>] ? call_timer_fn+0x5/0x350
[ 7858.218415]  [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.218656]  [<ffffffff810fde10>] run_timer_softirq+0x260/0x640
[ 7858.218865]  [<ffffffff8166379b>] ? __do_softirq+0xbb/0x54f
[ 7858.219068]  [<ffffffff816637c8>] __do_softirq+0xe8/0x54f
[ 7858.219269]  [<ffffffff8107a948>] irq_exit+0xb8/0xc0
[ 7858.219463]  [<ffffffff81663452>] smp_apic_timer_interrupt+0x42/0x50
[ 7858.219678]  [<ffffffff816625bc>] apic_timer_interrupt+0x8c/0xa0
[ 7858.219897]  <EOI>  [<ffffffff81055f16>] ? native_safe_halt+0x6/0x10
[ 7858.220165]  [<ffffffff810d64dd>] ? trace_hardirqs_on+0xd/0x10
[ 7858.220373]  [<ffffffff810298e3>] default_idle+0x23/0x190
[ 7858.220574]  [<ffffffff8102a20f>] arch_cpu_idle+0xf/0x20
[ 7858.220790]  [<ffffffff810c9f8c>] default_idle_call+0x4c/0x60
[ 7858.221016]  [<ffffffff810ca33b>] cpu_startup_entry+0x39b/0x4d0
[ 7858.221257]  [<ffffffff8164f995>] rest_init+0x135/0x140
[ 7858.221469]  [<ffffffff81f83014>] start_kernel+0x50e/0x51b
[ 7858.221670]  [<ffffffff81f82120>] ? early_idt_handler_array+0x120/0x120
[ 7858.221894]  [<ffffffff81f8243f>] x86_64_start_reservations+0x2a/0x2c
[ 7858.222113]  [<ffffffff81f8257c>] x86_64_start_kernel+0x13b/0x14a

Fixes: 2942e90050 ("[RTNETLINK]: Use rtnl_unicast() for rtnetlink unicasts")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2016-11-20 01:17:35 +00:00
..
netfilter netfilter: x_tables: speed up jump target validation 2016-11-20 01:16:53 +00:00
addrconf.c ipv6: addrconf: fix dev refcont leak when DAD failed 2016-11-20 01:17:23 +00:00
addrconf_core.c ipv6: remove rt6i_genid 2014-10-15 12:05:29 +02:00
addrlabel.c ipv6/addrlabel: fix ip6addrlbl_get() 2016-01-25 10:44:00 +00:00
af_inet6.c net: add validation for the socket syscall protocol argument 2016-01-04 17:20:45 +00:00
ah6.c ah6: Use the IPsec protocol multiplexer API 2014-03-14 07:28:07 +01:00
anycast.c ipv6: restore the behavior of ipv6_sock_ac_drop() 2014-10-15 12:05:28 +02:00
datagram.c ipv6/udp: use sticky pktinfo egress ifindex on connect() 2016-03-09 10:38:49 +00:00
esp6.c esp6: Use the IPsec protocol multiplexer API 2014-03-14 07:28:07 +01:00
exthdrs.c ipv6: add complete rcu protection around np->opt 2015-12-18 16:06:24 +00:00
exthdrs_core.c ipv6: re-enable fragment header matching in ipv6_find_hdr 2016-03-24 10:01:14 +00:00
exthdrs_offload.c ipv6: fix exthdrs offload registration in out_rt path 2015-09-30 13:20:50 +01:00
fib6_rules.c ipv6: fix backtracking for throw routes 2015-03-24 10:34:13 +00:00
icmp.c ipv6: fix endianness error in icmpv6_err 2016-08-22 22:38:15 +01:00
inet6_connection_sock.c ipv6: add complete rcu protection around np->opt 2015-12-18 16:06:24 +00:00
inet6_hashtables.c inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once 2013-10-19 19:45:35 -04:00
ip6_checksum.c udp: Generic functions to set checksum 2014-06-04 22:46:38 -07:00
ip6_fib.c ipv6: fix ECMP route replacement 2015-06-02 13:02:14 +01:00
ip6_flowlabel.c ipv6: fix a lockdep splat 2016-02-25 10:51:01 +00:00
ip6_gre.c ip6_gre: fix flowi6_proto value in ip6gre_xmit_other() 2016-11-20 01:17:35 +00:00
ip6_icmp.c ipv6: Kill ipv6 dependency of icmpv6_send(). 2013-04-29 13:54:36 -04:00
ip6_input.c ipv6: Make MLD packets to only be processed locally 2015-08-10 17:10:15 +01:00
ip6_offload.c net: gso: use feature flag argument in all protocol gso handlers 2015-08-27 14:27:14 +01:00
ip6_offload.h ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
ip6_output.c ipv6: Count in extension headers in skb->network_header 2016-05-01 00:06:15 +02:00
ip6_tunnel.c ip6_tunnel: set rtnl_link_ops before calling register_netdevice 2016-05-01 00:06:08 +02:00
ip6_vti.c vti6: fix uninit when using x-netns 2015-05-06 11:33:05 +01:00
ip6mr.c ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route 2016-11-20 01:17:35 +00:00
ipcomp6.c ipcomp6: Use the IPsec protocol multiplexer API 2014-03-14 07:28:07 +01:00
ipv6_sockglue.c ipv6: add complete rcu protection around np->opt 2015-12-18 16:06:24 +00:00
Kconfig ip6_vti: Fix build when NET_IP_TUNNEL is not set. 2014-02-20 14:29:49 +01:00
Makefile xfrm6: Add IPsec protocol multiplexer 2014-03-14 07:28:07 +01:00
mcast.c mld, igmp: Fix reserved tailroom calculation 2016-03-24 10:01:13 +00:00
mip6.c ipv4/ipv6: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
ndisc.c net/ipv6: add sysctl option accept_ra_min_hop_limit 2016-03-24 09:59:05 +00:00
netfilter.c netfilter: Fix potential use after free in ip6_route_me_harder() 2014-05-09 02:36:39 +02:00
output_core.c drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets 2014-12-10 17:49:35 +00:00
ping.c net: ping: Return EAFNOSUPPORT when appropriate. 2015-03-12 16:45:17 +00:00
proc.c snmp: fix some left over of snmp stats 2014-05-14 15:33:47 -04:00
protocol.c net: remove outdated comment for ipv4 and ipv6 protocol handler 2013-11-28 18:47:51 -05:00
raw.c Revert "[stable-only] net: add length argument to skb_copy_and_csum_datagram_iovec" 2016-01-25 10:44:07 +00:00
reassembly.c ipv6: distinguish frag queues by device for multicast and link-local packets 2015-12-18 16:06:23 +00:00
route.c ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route 2016-11-20 01:17:35 +00:00
sit.c sit: fix sit0 percpu double allocations 2015-12-09 11:40:54 +00:00
syncookies.c ipv6: add complete rcu protection around np->opt 2015-12-18 16:06:24 +00:00
sysctl_net_ipv6.c net: add a sysctl to reflect the fwmark on replies 2014-05-13 18:35:08 -04:00
tcp_ipv6.c tcp: record TLP and ER timer stats in v6 stats 2016-08-22 22:38:09 +01:00
tcpv6_offload.c net-gre-gro: Fix a bug that breaks the forwarding path 2014-07-16 14:45:26 -07:00
tunnel6.c ipv6: fix tunnel error handling 2015-12-13 17:49:43 +00:00
udp.c udp6: fix UDP/IPv6 encap resubmit path 2016-05-01 00:06:13 +02:00
udp_impl.h net: ipv4/ipv6: Remove extern from function prototypes 2013-10-19 19:12:11 -04:00
udp_offload.c gre: Call gso_make_checksum 2014-06-04 22:46:38 -07:00
udplite.c net: Eliminate no_check from protosw 2014-05-23 16:28:53 -04:00
xfrm6_input.c netfilter: ipv6: use NFPROTO values for NF_HOOK invocation 2010-03-25 16:00:49 +01:00
xfrm6_mode_beet.c ipsec: be careful of non existing mac headers 2012-02-23 16:50:45 -05:00
xfrm6_mode_ro.c ipv4/ipv6: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
xfrm6_mode_transport.c [IPSEC]: Use IPv6 calling convention as the convention for x->mode->output 2007-10-10 16:55:54 -07:00
xfrm6_mode_tunnel.c ipv6: update skb->csum when CE mark is propagated 2016-01-28 11:06:06 +00:00
xfrm6_output.c ipv6: Fix IPsec pre-encap fragmentation check 2015-11-16 11:27:17 +00:00
xfrm6_policy.c xfrm: dst_entries_init() per-net dst_ops 2016-01-28 11:57:51 +00:00
xfrm6_protocol.c xfrm6: Properly handle unsupported protocols 2014-05-06 07:08:38 +02:00
xfrm6_state.c xfrm: make local error reporting more robust 2013-08-14 13:07:12 +02:00
xfrm6_tunnel.c ipv4/ipv6: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00