linux/net/ipv6
Patrick McHardy 2bec5a369e ipv6: fib: fix crash when changing large fib while dumping it
When the fib size exceeds what can be dumped in a single skb, the
dump is suspended and resumed once the last skb has been received
by userspace. When the fib is changed while the dump is suspended,
the walker might contain stale pointers, causing a crash when the
dump is resumed.

BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
IP: [<ffffffffa01bce04>] fib6_walk_continue+0xbb/0x124 [ipv6]
PGD 5347a067 PUD 65c7067 PMD 0
Oops: 0000 [#1] PREEMPT SMP
...
RIP: 0010:[<ffffffffa01bce04>]
[<ffffffffa01bce04>] fib6_walk_continue+0xbb/0x124 [ipv6]
...
Call Trace:
 [<ffffffff8104aca3>] ? mutex_spin_on_owner+0x59/0x71
 [<ffffffffa01bd105>] inet6_dump_fib+0x11b/0x1b9 [ipv6]
 [<ffffffff81371af4>] netlink_dump+0x5b/0x19e
 [<ffffffff8134f288>] ? consume_skb+0x28/0x2a
 [<ffffffff81373b69>] netlink_recvmsg+0x1ab/0x2c6
 [<ffffffff81372781>] ? netlink_unicast+0xfa/0x151
 [<ffffffff813483e0>] __sock_recvmsg+0x6d/0x79
 [<ffffffff81348a53>] sock_recvmsg+0xca/0xe3
 [<ffffffff81066d4b>] ? autoremove_wake_function+0x0/0x38
 [<ffffffff811ed1f8>] ? radix_tree_lookup_slot+0xe/0x10
 [<ffffffff810b3ed7>] ? find_get_page+0x90/0xa5
 [<ffffffff810b5dc5>] ? filemap_fault+0x201/0x34f
 [<ffffffff810ef152>] ? fget_light+0x2f/0xac
 [<ffffffff813519e7>] ? verify_iovec+0x4f/0x94
 [<ffffffff81349a65>] sys_recvmsg+0x14d/0x223

Store the serial number when beginning to walk the fib and reload
pointers when continuing to walk after a change occured. Similar
to other dumping functions, this might cause unrelated entries to
be missed when entries are deleted.

Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2010-02-12 12:06:35 -08:00
..
netfilter netfilter: xtables: compat out of scope fix 2010-02-08 11:17:43 -08:00
addrconf_core.c [IPV6]: ipv6_addr_type() doesn't know about RFC4193 addresses. 2007-07-31 02:28:21 -07:00
addrconf.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
addrlabel.c net: replace %p6 with %pI6 2008-10-29 12:52:50 -07:00
af_inet6.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
ah6.c xfrm: Use the user specified truncation length in ESP and AH 2009-11-25 15:48:41 -08:00
anycast.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
datagram.c ipv6: no more dev_put() in datagram_send_ctl() 2009-11-02 03:42:41 -08:00
esp6.c xfrm: Use the user specified truncation length in ESP and AH 2009-11-25 15:48:41 -08:00
exthdrs_core.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
exthdrs.c ipv6: skb_dst() can be NULL in ipv6_hop_jumbo(). 2010-01-13 17:27:37 -08:00
fib6_rules.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
icmp.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
inet6_connection_sock.c net: IPv6 changes 2009-10-20 18:55:45 -07:00
inet6_hashtables.c tcp: Fix a connect() race with timewait sockets 2009-12-08 20:17:51 -08:00
ip6_fib.c ipv6: fib: fix crash when changing large fib while dumping it 2010-02-12 12:06:35 -08:00
ip6_flowlabel.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
ip6_input.c net: constify struct inet6_protocol 2009-09-14 17:03:05 -07:00
ip6_output.c ip: fix mc_loop checks for tunnels with multicast outer addresses 2010-01-06 20:37:01 -08:00
ip6_tunnel.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
ip6mr.c ip6mr: Optimize multiple unregistration 2009-10-29 01:13:53 -07:00
ipcomp6.c netns xfrm: ipcomp6 support 2010-01-28 06:31:06 -08:00
ipv6_sockglue.c Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 2009-10-27 01:03:26 -07:00
Kconfig IPv6: Fix 6RD typo 2009-10-07 14:50:30 -07:00
Makefile [IPV6] MROUTE: Support multicast forwarding. 2008-04-05 22:33:38 +09:00
mcast.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
mip6.c ipv6: Use correct data types for ICMPv6 type and code 2009-06-23 04:31:07 -07:00
ndisc.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
netfilter.c net: skb->dst accessors 2009-06-03 02:51:04 -07:00
proc.c net: constify MIB name tables 2010-01-23 01:21:27 -08:00
protocol.c net: constify struct inet6_protocol 2009-09-14 17:03:05 -07:00
raw.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
reassembly.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
route.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
sit.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
syncookies.c net: Add rtnetlink init_rcvwnd to set the TCP initial receive window 2009-12-23 14:13:30 -08:00
sysctl_net_ipv6.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
tcp_ipv6.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
tunnel6.c net: constify struct inet6_protocol 2009-09-14 17:03:05 -07:00
udp_impl.h net: Make setsockopt() optlen be unsigned. 2009-09-30 16:12:20 -07:00
udp.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
udplite.c net: spread __net_init, __net_exit 2010-01-17 19:16:02 -08:00
xfrm6_input.c netns xfrm: per-netns MIBs 2008-11-25 17:59:52 -08:00
xfrm6_mode_beet.c ipsec: Interfamily IPSec BEET, ipv4-inner ipv6-outer 2008-08-06 02:40:25 -07:00
xfrm6_mode_ro.c [IPSEC]: Make x->lastused an unsigned long 2008-01-28 14:53:52 -08: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 net: skb->dst accessors 2009-06-03 02:51:04 -07:00
xfrm6_output.c net: skb->dst accessors 2009-06-03 02:51:04 -07:00
xfrm6_policy.c netns xfrm: deal with dst entries in netns 2010-01-24 22:47:53 -08:00
xfrm6_state.c ipv6: fix sparse warning: Using plain integer as NULL pointer 2009-02-21 23:37:10 -08:00
xfrm6_tunnel.c netns xfrm: xfrm6_tunnel in netns 2010-01-28 06:31:05 -08:00