* [Patch net] ipv6: initialize route null entry in addrconf_init()
@ 2017-05-04 5:07 Cong Wang
2017-05-04 12:28 ` Andrey Konovalov
0 siblings, 1 reply; 5+ messages in thread
From: Cong Wang @ 2017-05-04 5:07 UTC (permalink / raw)
To: netdev; +Cc: andreyknvl, dsahern, Cong Wang
Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev
since it is always NULL.
This is clearly wrong, we have code to initialize it to loopback_dev,
unfortunately the order is still not correct.
loopback_dev is registered very early during boot, we lose a chance
to re-initialize it in notifier. addrconf_init() is called after
ip6_route_init(), which means we have no chance to correct it.
Fix it by moving this initialization explicitly after
ipv6_add_dev(init_net.loopback_dev) in addrconf_init().
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
include/net/ip6_route.h | 1 +
net/ipv6/addrconf.c | 2 ++
net/ipv6/route.c | 26 +++++++++++++++-----------
3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 9dc2c18..f5e625f 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -84,6 +84,7 @@ struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
int ifindex, struct flowi6 *fl6, int flags);
+void ip6_route_init_special_entries(void);
int ip6_route_init(void);
void ip6_route_cleanup(void);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a2a370b..77a4bd5 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6573,6 +6573,8 @@ int __init addrconf_init(void)
goto errlo;
}
+ ip6_route_init_special_entries();
+
for (i = 0; i < IN6_ADDR_HSIZE; i++)
INIT_HLIST_HEAD(&inet6_addr_lst[i]);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a1bf426..2f11366 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4027,6 +4027,21 @@ static struct notifier_block ip6_route_dev_notifier = {
.priority = 0,
};
+void __init ip6_route_init_special_entries(void)
+{
+ /* Registering of the loopback is done before this portion of code,
+ * the loopback reference in rt6_info will not be taken, do it
+ * manually for init_net */
+ init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
+ init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
+ init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
+ init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ #endif
+}
+
int __init ip6_route_init(void)
{
int ret;
@@ -4053,17 +4068,6 @@ int __init ip6_route_init(void)
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
- /* Registering of the loopback is done before this portion of code,
- * the loopback reference in rt6_info will not be taken, do it
- * manually for init_net */
- init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
- init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
- init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
- init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- #endif
ret = fib6_init();
if (ret)
goto out_register_subsys;
--
2.5.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Patch net] ipv6: initialize route null entry in addrconf_init()
2017-05-04 5:07 [Patch net] ipv6: initialize route null entry in addrconf_init() Cong Wang
@ 2017-05-04 12:28 ` Andrey Konovalov
2017-05-04 16:51 ` David Miller
0 siblings, 1 reply; 5+ messages in thread
From: Andrey Konovalov @ 2017-05-04 12:28 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, David Ahern
On Thu, May 4, 2017 at 7:07 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev
> since it is always NULL.
>
> This is clearly wrong, we have code to initialize it to loopback_dev,
> unfortunately the order is still not correct.
>
> loopback_dev is registered very early during boot, we lose a chance
> to re-initialize it in notifier. addrconf_init() is called after
> ip6_route_init(), which means we have no chance to correct it.
>
> Fix it by moving this initialization explicitly after
> ipv6_add_dev(init_net.loopback_dev) in addrconf_init().
>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Hi Cong,
This fixes the bug triggered by my reproducer.
Thanks!
Tested-by: Andrey Konovalov <andreyknvl@google.com>
> ---
> include/net/ip6_route.h | 1 +
> net/ipv6/addrconf.c | 2 ++
> net/ipv6/route.c | 26 +++++++++++++++-----------
> 3 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
> index 9dc2c18..f5e625f 100644
> --- a/include/net/ip6_route.h
> +++ b/include/net/ip6_route.h
> @@ -84,6 +84,7 @@ struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
> struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
> int ifindex, struct flowi6 *fl6, int flags);
>
> +void ip6_route_init_special_entries(void);
> int ip6_route_init(void);
> void ip6_route_cleanup(void);
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index a2a370b..77a4bd5 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -6573,6 +6573,8 @@ int __init addrconf_init(void)
> goto errlo;
> }
>
> + ip6_route_init_special_entries();
> +
> for (i = 0; i < IN6_ADDR_HSIZE; i++)
> INIT_HLIST_HEAD(&inet6_addr_lst[i]);
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index a1bf426..2f11366 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -4027,6 +4027,21 @@ static struct notifier_block ip6_route_dev_notifier = {
> .priority = 0,
> };
>
> +void __init ip6_route_init_special_entries(void)
> +{
> + /* Registering of the loopback is done before this portion of code,
> + * the loopback reference in rt6_info will not be taken, do it
> + * manually for init_net */
> + init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
> + init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
> + init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
> + init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> + init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
> + init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> + #endif
> +}
> +
> int __init ip6_route_init(void)
> {
> int ret;
> @@ -4053,17 +4068,6 @@ int __init ip6_route_init(void)
>
> ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
>
> - /* Registering of the loopback is done before this portion of code,
> - * the loopback reference in rt6_info will not be taken, do it
> - * manually for init_net */
> - init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
> - init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> - #ifdef CONFIG_IPV6_MULTIPLE_TABLES
> - init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
> - init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> - init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
> - init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
> - #endif
> ret = fib6_init();
> if (ret)
> goto out_register_subsys;
> --
> 2.5.5
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Patch net] ipv6: initialize route null entry in addrconf_init()
2017-05-04 12:28 ` Andrey Konovalov
@ 2017-05-04 16:51 ` David Miller
2017-05-04 17:12 ` David Ahern
0 siblings, 1 reply; 5+ messages in thread
From: David Miller @ 2017-05-04 16:51 UTC (permalink / raw)
To: andreyknvl; +Cc: xiyou.wangcong, netdev, dsahern
From: Andrey Konovalov <andreyknvl@google.com>
Date: Thu, 4 May 2017 14:28:37 +0200
> On Thu, May 4, 2017 at 7:07 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>> Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev
>> since it is always NULL.
>>
>> This is clearly wrong, we have code to initialize it to loopback_dev,
>> unfortunately the order is still not correct.
>>
>> loopback_dev is registered very early during boot, we lose a chance
>> to re-initialize it in notifier. addrconf_init() is called after
>> ip6_route_init(), which means we have no chance to correct it.
>>
>> Fix it by moving this initialization explicitly after
>> ipv6_add_dev(init_net.loopback_dev) in addrconf_init().
>>
>> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
>
> Hi Cong,
>
> This fixes the bug triggered by my reproducer.
>
> Thanks!
>
> Tested-by: Andrey Konovalov <andreyknvl@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Patch net] ipv6: initialize route null entry in addrconf_init()
2017-05-04 16:51 ` David Miller
@ 2017-05-04 17:12 ` David Ahern
2017-05-04 17:19 ` Cong Wang
0 siblings, 1 reply; 5+ messages in thread
From: David Ahern @ 2017-05-04 17:12 UTC (permalink / raw)
To: David Miller, andreyknvl, xiyou.wangcong; +Cc: netdev
On 5/4/17 10:51 AM, David Miller wrote:
> From: Andrey Konovalov <andreyknvl@google.com>
> Date: Thu, 4 May 2017 14:28:37 +0200
>
>> On Thu, May 4, 2017 at 7:07 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>> Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev
>>> since it is always NULL.
>>>
>>> This is clearly wrong, we have code to initialize it to loopback_dev,
>>> unfortunately the order is still not correct.
>>>
>>> loopback_dev is registered very early during boot, we lose a chance
>>> to re-initialize it in notifier. addrconf_init() is called after
>>> ip6_route_init(), which means we have no chance to correct it.
>>>
>>> Fix it by moving this initialization explicitly after
>>> ipv6_add_dev(init_net.loopback_dev) in addrconf_init().
>>>
>>> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>>> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
>>
>> Hi Cong,
>>
>> This fixes the bug triggered by my reproducer.
>>
>> Thanks!
>>
>> Tested-by: Andrey Konovalov <andreyknvl@google.com>
>
> Applied and queued up for -stable, thanks.
>
This is not the complete solution; it only fixes init_net. It still
blows up when you do:
unshare -n
./rt6_device_match
same exact stack trace
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Patch net] ipv6: initialize route null entry in addrconf_init()
2017-05-04 17:12 ` David Ahern
@ 2017-05-04 17:19 ` Cong Wang
0 siblings, 0 replies; 5+ messages in thread
From: Cong Wang @ 2017-05-04 17:19 UTC (permalink / raw)
To: David Ahern
Cc: David Miller, Andrey Konovalov, Linux Kernel Network Developers
On Thu, May 4, 2017 at 10:12 AM, David Ahern <dsahern@gmail.com> wrote:
> On 5/4/17 10:51 AM, David Miller wrote:
>> From: Andrey Konovalov <andreyknvl@google.com>
>> Date: Thu, 4 May 2017 14:28:37 +0200
>>
>>> On Thu, May 4, 2017 at 7:07 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>> Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev
>>>> since it is always NULL.
>>>>
>>>> This is clearly wrong, we have code to initialize it to loopback_dev,
>>>> unfortunately the order is still not correct.
>>>>
>>>> loopback_dev is registered very early during boot, we lose a chance
>>>> to re-initialize it in notifier. addrconf_init() is called after
>>>> ip6_route_init(), which means we have no chance to correct it.
>>>>
>>>> Fix it by moving this initialization explicitly after
>>>> ipv6_add_dev(init_net.loopback_dev) in addrconf_init().
>>>>
>>>> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>>>> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
>>>
>>> Hi Cong,
>>>
>>> This fixes the bug triggered by my reproducer.
>>>
>>> Thanks!
>>>
>>> Tested-by: Andrey Konovalov <andreyknvl@google.com>
>>
>> Applied and queued up for -stable, thanks.
>>
>
> This is not the complete solution; it only fixes init_net. It still
> blows up when you do:
>
> unshare -n
> ./rt6_device_match
>
>
> same exact stack trace
This is why I sent
[Patch net] ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-05-04 17:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-04 5:07 [Patch net] ipv6: initialize route null entry in addrconf_init() Cong Wang
2017-05-04 12:28 ` Andrey Konovalov
2017-05-04 16:51 ` David Miller
2017-05-04 17:12 ` David Ahern
2017-05-04 17:19 ` Cong Wang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.