* [PATCH net-next] net: ipv6: ignore null_entry on route dumps
@ 2017-01-23 4:56 David Ahern
2017-01-23 4:58 ` David Miller
0 siblings, 1 reply; 6+ messages in thread
From: David Ahern @ 2017-01-23 4:56 UTC (permalink / raw)
To: netdev; +Cc: xiaolong.ye, David Ahern
lkp-robot reported a BUG:
[ 10.151226] BUG: unable to handle kernel NULL pointer dereference at 00000198
[ 10.152525] IP: rt6_fill_node+0x164/0x4b8
[ 10.153307] *pdpt = 0000000012ee5001 *pde = 0000000000000000
[ 10.153309]
[ 10.154492] Oops: 0000 [#1]
[ 10.154987] CPU: 0 PID: 909 Comm: netifd Not tainted 4.10.0-rc4-00722-g41e8c70ee162-dirty #10
[ 10.156482] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
[ 10.158254] task: d0deb000 task.stack: d0e0c000
[ 10.159059] EIP: rt6_fill_node+0x164/0x4b8
[ 10.159780] EFLAGS: 00010296 CPU: 0
[ 10.160404] EAX: 00000000 EBX: d10c2358 ECX: c1f7c6cc EDX: c1f6ff44
[ 10.161469] ESI: 00000000 EDI: c2059900 EBP: d0e0dc4c ESP: d0e0dbe4
[ 10.162534] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[ 10.163482] CR0: 80050033 CR2: 00000198 CR3: 10d94660 CR4: 000006b0
[ 10.164535] Call Trace:
[ 10.164993] ? paravirt_sched_clock+0x9/0xd
[ 10.165727] ? sched_clock+0x9/0xc
[ 10.166329] ? sched_clock_cpu+0x19/0xe9
[ 10.166991] ? lock_release+0x13e/0x36c
[ 10.167652] rt6_dump_route+0x4c/0x56
[ 10.168276] fib6_dump_node+0x1d/0x3d
[ 10.168913] fib6_walk_continue+0xab/0x167
[ 10.169611] fib6_walk+0x2a/0x40
[ 10.170182] inet6_dump_fib+0xfb/0x1e0
[ 10.170855] netlink_dump+0xcd/0x21f
This happens when the loopback device is set down and a ipv6 fib route
dump is requested.
The ipv6 route dump code passes ip6_null_entry to rt6_fill_node. This
route uses the loopback device but does not have idev set. When the
loopback is set down, the netif_running check added by a1a22c1206 fails
and the fill_node descends to checking rt->rt6i_idev for
ignore_routes_with_linkdown. Since idev is null for the ip6_null_entry
route it triggers the BUG.
The null_entry route should not be processed in a dump request. Catch
and ignore.
Fixes: a1a22c1206("net: ipv6: Keep nexthop of multipath route on admin down")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
net/ipv6/route.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4b1f0f98a0e9..47499ed429da 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3320,6 +3320,10 @@ static int rt6_fill_node(struct net *net,
int rt6_dump_route(struct rt6_info *rt, void *p_arg)
{
struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
+ struct net *net = arg->net;
+
+ if (rt == net->ipv6.ip6_null_entry)
+ return 0;
if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
@@ -3332,7 +3336,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
}
}
- return rt6_fill_node(arg->net,
+ return rt6_fill_node(net,
arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
NLM_F_MULTI);
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH net-next] net: ipv6: ignore null_entry on route dumps
2017-01-23 4:56 [PATCH net-next] net: ipv6: ignore null_entry on route dumps David Ahern
@ 2017-01-23 4:58 ` David Miller
2017-01-23 16:51 ` David Ahern
0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2017-01-23 4:58 UTC (permalink / raw)
To: dsa; +Cc: netdev, xiaolong.ye
David, please slow down.
How is the NULL entry getting selected to be dumped and passed
down here in the first place?
The problem seems to be higher up in the chain here, don't
just special case check for this in rt6_dump_route().
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next] net: ipv6: ignore null_entry on route dumps
2017-01-23 4:58 ` David Miller
@ 2017-01-23 16:51 ` David Ahern
2017-01-25 1:35 ` David Ahern
0 siblings, 1 reply; 6+ messages in thread
From: David Ahern @ 2017-01-23 16:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, xiaolong.ye
On 1/22/17 9:58 PM, David Miller wrote:
>
> David, please slow down.
>
> How is the NULL entry getting selected to be dumped and passed
> down here in the first place?
The null_entry might be a 'marker' but is integral to the ipv6 fib. For starters:
static int __net_init fib6_net_init(struct net *net)
{
...
net->ipv6.fib6_main_tbl = kzalloc(sizeof(*net->ipv6.fib6_main_tbl),
GFP_KERNEL);
...
net->ipv6.fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
net->ipv6.fib6_main_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry;
...
Same goes for every other table allocated:
static struct fib6_table *fib6_alloc_table(struct net *net, u32 id)
{
struct fib6_table *table;
table = kzalloc(sizeof(*table), GFP_ATOMIC);
if (table) {
table->tb6_id = id;
table->tb6_root.leaf = net->ipv6.ip6_null_entry;
..
}
And if you look at the fib6_add code:
sfn->leaf = info->nl_net->ipv6.ip6_null_entry;
atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref);
sfn->fn_flags = RTN_ROOT;
sfn->fn_sernum = sernum;
/* Now add the first leaf node to new subtree */
sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
rt->rt6i_src.plen,
offsetof(struct rt6_info, rt6i_src),
allow_create, replace_required, sernum);
Meaning that a walk of the table is going to dump the ip6_null_entry route, potentially multiple times.
As far as the dump request the chain rtnetlink message invokes inet6_dump_fib:
inet6_dump_fib
- fib6_dump_table
+ fib6_walk
* fib6_walk_continue
- fib6_dump_node
+ rt6_dump_route
Seems to me the most appropriate place to check that rt is the null_entry route is rt6_dump_route but perhaps fib6_dump_node could as well. This patch buts the check in rt6_dump_route.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH net-next] net: ipv6: ignore null_entry on route dumps
2017-01-23 16:51 ` David Ahern
@ 2017-01-25 1:35 ` David Ahern
2017-01-25 1:39 ` David Miller
0 siblings, 1 reply; 6+ messages in thread
From: David Ahern @ 2017-01-25 1:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev, xiaolong.ye
On 1/23/17 9:51 AM, David Ahern wrote:
> On 1/22/17 9:58 PM, David Miller wrote:
>> David, please slow down.
>>
>> How is the NULL entry getting selected to be dumped and passed
>> down here in the first place?
> The null_entry might be a 'marker' but is integral to the ipv6 fib.
As I mentioned in my last response the null_entry is tb6_root.leaf for all tables making it part of the table. Since the dump walks the table and sends each route to rt6_dump_route, the dump includes the null_entry.
ip6_null_entry->rt6i_idev is NULL because ip6_route_net_init is run before addrconf_init has initialized the loopback device.
Given that, it seems like a check is needed somewhere ... be it 'rt == net->ipv6.ip6_null_entry' in rt6_dump_route or fib6_dump_node, or a check for rt6i_idev NULL in rt6_fill_node.
You marked the last patch as changes needed meaning another needs to be sent.
Suggestion?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next] net: ipv6: ignore null_entry on route dumps
2017-01-25 1:35 ` David Ahern
@ 2017-01-25 1:39 ` David Miller
2017-01-25 4:07 ` David Ahern
0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2017-01-25 1:39 UTC (permalink / raw)
To: dsa; +Cc: netdev, xiaolong.ye
From: David Ahern <dsa@cumulusnetworks.com>
Date: Tue, 24 Jan 2017 18:35:02 -0700
> On 1/23/17 9:51 AM, David Ahern wrote:
>> On 1/22/17 9:58 PM, David Miller wrote:
>>> David, please slow down.
>>>
>>> How is the NULL entry getting selected to be dumped and passed
>>> down here in the first place?
>> The null_entry might be a 'marker' but is integral to the ipv6 fib.
>
> As I mentioned in my last response the null_entry is tb6_root.leaf for all tables making it part of the table. Since the dump walks the table and sends each route to rt6_dump_route, the dump includes the null_entry.
>
> ip6_null_entry->rt6i_idev is NULL because ip6_route_net_init is run before addrconf_init has initialized the loopback device.
>
> Given that, it seems like a check is needed somewhere ... be it 'rt == net->ipv6.ip6_null_entry' in rt6_dump_route or fib6_dump_node, or a check for rt6i_idev NULL in rt6_fill_node.
>
> You marked the last patch as changes needed meaning another needs to be sent.
>
> Suggestion?
Probably putting the check as high in the call chain as possible, via
fib6_dump_node(), is the best.
Although, it's troubling that we are trying to dump unfinished entries
simply because of initialization order. It's arguable that this is
the real thing to fix.
The loopback device is a hard dependency which the ipv6 stack has
because of how it does statistics and other things.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-01-25 4:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-23 4:56 [PATCH net-next] net: ipv6: ignore null_entry on route dumps David Ahern
2017-01-23 4:58 ` David Miller
2017-01-23 16:51 ` David Ahern
2017-01-25 1:35 ` David Ahern
2017-01-25 1:39 ` David Miller
2017-01-25 4:07 ` David Ahern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).