* [PATCH net 0/2] fix two kernel panics when disabled IPv6 on boot up
@ 2019-02-06 12:51 Hangbin Liu
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-06 12:51 UTC (permalink / raw)
To: netdev; +Cc: Stefano Brivio, David Miller, Hangbin Liu
When disabled IPv6 on boot up, since there is no ipv6 route tables, we should
not call rt6_lookup. Fix them by checking if we have inet6_dev pointer on
netdevice.
Hangbin Liu (2):
geneve: should not call rt6_lookup() when ipv6 was disabled
sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach()
drivers/net/geneve.c | 6 ++++++
net/ipv6/sit.c | 8 +++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
--
2.19.2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 12:51 [PATCH net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
@ 2019-02-06 12:51 ` Hangbin Liu
2019-02-06 14:58 ` Stefano Brivio
` (3 more replies)
2019-02-06 12:51 ` [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach() Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2 siblings, 4 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-06 12:51 UTC (permalink / raw)
To: netdev; +Cc: Stefano Brivio, David Miller, Hangbin Liu
When we add a new GENEVE device with IPv6 remote, checking only for
IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
drivers/net/geneve.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 58bbba8582b0..0658715581e3 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
}
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6: {
+ struct inet6_dev *idev = in6_dev_get(dev);
+ if (!idev)
+ break;
+
struct rt6_info *rt = rt6_lookup(geneve->net,
&info->key.u.ipv6.dst, NULL, 0,
NULL, 0);
@@ -1519,6 +1523,8 @@ static void geneve_link_config(struct net_device *dev,
if (rt && rt->dst.dev)
ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
ip6_rt_put(rt);
+
+ in6_dev_put(idev);
break;
}
#endif
--
2.19.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach()
2019-02-06 12:51 [PATCH net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
@ 2019-02-06 12:51 ` Hangbin Liu
2019-02-06 15:00 ` Stefano Brivio
2019-02-06 16:45 ` Eric Dumazet
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2 siblings, 2 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-06 12:51 UTC (permalink / raw)
To: netdev; +Cc: Stefano Brivio, David Miller, Hangbin Liu
If we disabled IPv6 from kernel boot up cmd(ipv6.disable=1), we should not
call ip6_err_gen_icmpv6_unreach().
Reproducer:
ip link add sit1 type sit local 10.10.0.1 remote 10.10.1.1 ttl 1
ip link set sit1 up
ip addr add 192.168.0.1/24 dev sit1
ping 192.168.0.2
Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
net/ipv6/sit.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1e03305c0549..e43fbac0fd1a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -493,6 +493,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
unsigned int data_len = 0;
+ struct inet6_dev *idev;
struct ip_tunnel *t;
int sifindex;
int err;
@@ -546,8 +547,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
}
err = 0;
- if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
+
+ idev = in6_dev_get(skb->dev);
+ if (idev &&
+ !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len)) {
+ in6_dev_put(idev);
goto out;
+ }
if (t->parms.iph.daddr == 0)
goto out;
--
2.19.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
@ 2019-02-06 14:58 ` Stefano Brivio
2019-02-06 16:43 ` Eric Dumazet
` (2 subsequent siblings)
3 siblings, 0 replies; 16+ messages in thread
From: Stefano Brivio @ 2019-02-06 14:58 UTC (permalink / raw)
To: Hangbin Liu; +Cc: netdev, David Miller
Hi Hangbin,
On Wed, 6 Feb 2019 20:51:10 +0800
Hangbin Liu <liuhangbin@gmail.com> wrote:
> When we add a new GENEVE device with IPv6 remote, checking only for
> IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
> cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
>
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> drivers/net/geneve.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index 58bbba8582b0..0658715581e3 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
> }
> #if IS_ENABLED(CONFIG_IPV6)
> case AF_INET6: {
> + struct inet6_dev *idev = in6_dev_get(dev);
> + if (!idev)
> + break;
> +
> struct rt6_info *rt = rt6_lookup(geneve->net,
> &info->key.u.ipv6.dst, NULL, 0,
> NULL, 0);
You're mixing declarations and code here, ISO C90 forbids it. You
could rather declare:
struct inet6_dev *idev = in6_dev_get(dev);
struct rt6_info *rt;
then check idev, and then call rt6_lookup().
> @@ -1519,6 +1523,8 @@ static void geneve_link_config(struct net_device *dev,
> if (rt && rt->dst.dev)
> ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
> ip6_rt_put(rt);
> +
> + in6_dev_put(idev);
I think it would be better to put this right after the check on idev,
mostly for readability, but also, marginally, to reduce the scope of
the reference count bump.
--
Stefano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach()
2019-02-06 12:51 ` [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach() Hangbin Liu
@ 2019-02-06 15:00 ` Stefano Brivio
2019-02-06 16:45 ` Eric Dumazet
1 sibling, 0 replies; 16+ messages in thread
From: Stefano Brivio @ 2019-02-06 15:00 UTC (permalink / raw)
To: Hangbin Liu; +Cc: netdev, David Miller
On Wed, 6 Feb 2019 20:51:11 +0800
Hangbin Liu <liuhangbin@gmail.com> wrote:
> If we disabled IPv6 from kernel boot up cmd(ipv6.disable=1), we should not
> call ip6_err_gen_icmpv6_unreach().
>
> Reproducer:
> ip link add sit1 type sit local 10.10.0.1 remote 10.10.1.1 ttl 1
> ip link set sit1 up
> ip addr add 192.168.0.1/24 dev sit1
> ping 192.168.0.2
>
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> net/ipv6/sit.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
> index 1e03305c0549..e43fbac0fd1a 100644
> --- a/net/ipv6/sit.c
> +++ b/net/ipv6/sit.c
> @@ -493,6 +493,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
> const int type = icmp_hdr(skb)->type;
> const int code = icmp_hdr(skb)->code;
> unsigned int data_len = 0;
> + struct inet6_dev *idev;
> struct ip_tunnel *t;
> int sifindex;
> int err;
> @@ -546,8 +547,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
> }
>
> err = 0;
> - if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
> +
> + idev = in6_dev_get(skb->dev);
> + if (idev &&
> + !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len)) {
> + in6_dev_put(idev);
> goto out;
> + }
You are leaking a reference if idev && ip6_err_gen_icmpv6_unreach(...).
You should call in6_dev_put(idev) whenever idev is not NULL instead.
--
Stefano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-06 14:58 ` Stefano Brivio
@ 2019-02-06 16:43 ` Eric Dumazet
2019-02-06 18:54 ` David Ahern
2019-02-07 0:55 ` kbuild test robot
3 siblings, 0 replies; 16+ messages in thread
From: Eric Dumazet @ 2019-02-06 16:43 UTC (permalink / raw)
To: Hangbin Liu, netdev; +Cc: Stefano Brivio, David Miller
On 02/06/2019 04:51 AM, Hangbin Liu wrote:
> When we add a new GENEVE device with IPv6 remote, checking only for
> IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
> cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
>
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> drivers/net/geneve.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index 58bbba8582b0..0658715581e3 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
> }
> #if IS_ENABLED(CONFIG_IPV6)
> case AF_INET6: {
> + struct inet6_dev *idev = in6_dev_get(dev);
> + if (!idev)
> + break;
Do not mix declarations and code.
Instead, use :
struct inet6_dev *idev = in6_dev_get(dev);
struct rt6_info *rt;
if (!idev)
break;
rt = rt6_lookup(geneve->net, ...);
> +
> struct rt6_info *rt = rt6_lookup(geneve->net,
> &info->key.u.ipv6.dst, NULL, 0,
> NULL, 0);
> @@ -1519,6 +1523,8 @@ static void geneve_link_config(struct net_device *dev,
> if (rt && rt->dst.dev)
> ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
> ip6_rt_put(rt);
> +
> + in6_dev_put(idev);
> break;
> }
> #endif
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach()
2019-02-06 12:51 ` [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach() Hangbin Liu
2019-02-06 15:00 ` Stefano Brivio
@ 2019-02-06 16:45 ` Eric Dumazet
1 sibling, 0 replies; 16+ messages in thread
From: Eric Dumazet @ 2019-02-06 16:45 UTC (permalink / raw)
To: Hangbin Liu, netdev; +Cc: Stefano Brivio, David Miller
On 02/06/2019 04:51 AM, Hangbin Liu wrote:
> If we disabled IPv6 from kernel boot up cmd(ipv6.disable=1), we should not
> call ip6_err_gen_icmpv6_unreach().
>
> Reproducer:
> ip link add sit1 type sit local 10.10.0.1 remote 10.10.1.1 ttl 1
> ip link set sit1 up
> ip addr add 192.168.0.1/24 dev sit1
> ping 192.168.0.2
>
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> net/ipv6/sit.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
> index 1e03305c0549..e43fbac0fd1a 100644
> --- a/net/ipv6/sit.c
> +++ b/net/ipv6/sit.c
> @@ -493,6 +493,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
> const int type = icmp_hdr(skb)->type;
> const int code = icmp_hdr(skb)->code;
> unsigned int data_len = 0;
> + struct inet6_dev *idev;
> struct ip_tunnel *t;
> int sifindex;
> int err;
> @@ -546,8 +547,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
> }
>
> err = 0;
> - if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
> +
> + idev = in6_dev_get(skb->dev);
> + if (idev &&
> + !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len)) {
> + in6_dev_put(idev);
> goto out;
> + }
>
It seems there is a missing in6_dev_put(idev) depending on ip6_err_gen_icmpv6_unreach()() return value ?
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-06 14:58 ` Stefano Brivio
2019-02-06 16:43 ` Eric Dumazet
@ 2019-02-06 18:54 ` David Ahern
2019-02-06 19:04 ` Stefano Brivio
2019-02-06 19:08 ` Eric Dumazet
2019-02-07 0:55 ` kbuild test robot
3 siblings, 2 replies; 16+ messages in thread
From: David Ahern @ 2019-02-06 18:54 UTC (permalink / raw)
To: Hangbin Liu, netdev; +Cc: Stefano Brivio, David Miller
On 2/6/19 4:51 AM, Hangbin Liu wrote:
> When we add a new GENEVE device with IPv6 remote, checking only for
> IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
> cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
>
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> drivers/net/geneve.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index 58bbba8582b0..0658715581e3 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
> }
> #if IS_ENABLED(CONFIG_IPV6)
> case AF_INET6: {
> + struct inet6_dev *idev = in6_dev_get(dev);
> + if (!idev)
> + break;
Since you don't need an idev reference rcu_access_pointer should be
enough to say v6 is enabled on this device. ie., add a helper to check
that rcu_access_pointer(dev->ip6_ptr) is non-NULL
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 18:54 ` David Ahern
@ 2019-02-06 19:04 ` Stefano Brivio
2019-02-06 19:09 ` Eric Dumazet
2019-02-06 19:08 ` Eric Dumazet
1 sibling, 1 reply; 16+ messages in thread
From: Stefano Brivio @ 2019-02-06 19:04 UTC (permalink / raw)
To: David Ahern; +Cc: Hangbin Liu, netdev, David Miller
On Wed, 6 Feb 2019 10:54:01 -0800
David Ahern <dsahern@gmail.com> wrote:
> On 2/6/19 4:51 AM, Hangbin Liu wrote:
> > When we add a new GENEVE device with IPv6 remote, checking only for
> > IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
> > cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
> >
> > Reported-by: Jianlin Shi <jishi@redhat.com>
> > Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> > ---
> > drivers/net/geneve.c | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> > index 58bbba8582b0..0658715581e3 100644
> > --- a/drivers/net/geneve.c
> > +++ b/drivers/net/geneve.c
> > @@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
> > }
> > #if IS_ENABLED(CONFIG_IPV6)
> > case AF_INET6: {
> > + struct inet6_dev *idev = in6_dev_get(dev);
> > + if (!idev)
> > + break;
>
> Since you don't need an idev reference rcu_access_pointer should be
> enough to say v6 is enabled on this device. ie., add a helper to check
> that rcu_access_pointer(dev->ip6_ptr) is non-NULL
I guess if (__in6_dev_get(dev)) is already good, no? This is called
under RTNL.
--
Stefano
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 18:54 ` David Ahern
2019-02-06 19:04 ` Stefano Brivio
@ 2019-02-06 19:08 ` Eric Dumazet
1 sibling, 0 replies; 16+ messages in thread
From: Eric Dumazet @ 2019-02-06 19:08 UTC (permalink / raw)
To: David Ahern, Hangbin Liu, netdev; +Cc: Stefano Brivio, David Miller
On 02/06/2019 10:54 AM, David Ahern wrote:
> On 2/6/19 4:51 AM, Hangbin Liu wrote:
>> When we add a new GENEVE device with IPv6 remote, checking only for
>> IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in kernel
>> cmd(ipv6.disable=1), which will cause a NULL pointer dereference.
>>
>> Reported-by: Jianlin Shi <jishi@redhat.com>
>> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
>> ---
>> drivers/net/geneve.c | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
>> index 58bbba8582b0..0658715581e3 100644
>> --- a/drivers/net/geneve.c
>> +++ b/drivers/net/geneve.c
>> @@ -1512,6 +1512,10 @@ static void geneve_link_config(struct net_device *dev,
>> }
>> #if IS_ENABLED(CONFIG_IPV6)
>> case AF_INET6: {
>> + struct inet6_dev *idev = in6_dev_get(dev);
>> + if (!idev)
>> + break;
>
> Since you don't need an idev reference rcu_access_pointer should be
> enough to say v6 is enabled on this device. ie., add a helper to check
> that rcu_access_pointer(dev->ip6_ptr) is non-NULL
>
I guess RTNL is held at this point, so we can use a lockdep enabled
accessor : __in6_dev_get()
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 19:04 ` Stefano Brivio
@ 2019-02-06 19:09 ` Eric Dumazet
0 siblings, 0 replies; 16+ messages in thread
From: Eric Dumazet @ 2019-02-06 19:09 UTC (permalink / raw)
To: Stefano Brivio, David Ahern; +Cc: Hangbin Liu, netdev, David Miller
On 02/06/2019 11:04 AM, Stefano Brivio wrote:
> I guess if (__in6_dev_get(dev)) is already good, no? This is called
> under RTNL.
>
Exactly ;)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
` (2 preceding siblings ...)
2019-02-06 18:54 ` David Ahern
@ 2019-02-07 0:55 ` kbuild test robot
3 siblings, 0 replies; 16+ messages in thread
From: kbuild test robot @ 2019-02-07 0:55 UTC (permalink / raw)
To: Hangbin Liu; +Cc: kbuild-all, netdev, Stefano Brivio, David Miller, Hangbin Liu
[-- Attachment #1: Type: text/plain, Size: 4504 bytes --]
Hi Hangbin,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Hangbin-Liu/fix-two-kernel-panics-when-disabled-IPv6-on-boot-up/20190207-071954
config: m68k-sun3_defconfig (attached as .config)
compiler: m68k-linux-gnu-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.2.0 make.cross ARCH=m68k
All warnings (new ones prefixed by >>):
drivers/net/geneve.c: In function 'geneve_link_config':
>> drivers/net/geneve.c:1519:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
struct rt6_info *rt = rt6_lookup(geneve->net,
^~~~~~
vim +1519 drivers/net/geneve.c
abe492b4f5 Tom Herbert 2015-12-10 1490
c40e89fd35 Alexey Kodanev 2018-04-19 1491 static void geneve_link_config(struct net_device *dev,
c40e89fd35 Alexey Kodanev 2018-04-19 1492 struct ip_tunnel_info *info, struct nlattr *tb[])
c40e89fd35 Alexey Kodanev 2018-04-19 1493 {
c40e89fd35 Alexey Kodanev 2018-04-19 1494 struct geneve_dev *geneve = netdev_priv(dev);
c40e89fd35 Alexey Kodanev 2018-04-19 1495 int ldev_mtu = 0;
c40e89fd35 Alexey Kodanev 2018-04-19 1496
c40e89fd35 Alexey Kodanev 2018-04-19 1497 if (tb[IFLA_MTU]) {
c40e89fd35 Alexey Kodanev 2018-04-19 1498 geneve_change_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
c40e89fd35 Alexey Kodanev 2018-04-19 1499 return;
c40e89fd35 Alexey Kodanev 2018-04-19 1500 }
c40e89fd35 Alexey Kodanev 2018-04-19 1501
c40e89fd35 Alexey Kodanev 2018-04-19 1502 switch (ip_tunnel_info_af(info)) {
c40e89fd35 Alexey Kodanev 2018-04-19 1503 case AF_INET: {
c40e89fd35 Alexey Kodanev 2018-04-19 1504 struct flowi4 fl4 = { .daddr = info->key.u.ipv4.dst };
c40e89fd35 Alexey Kodanev 2018-04-19 1505 struct rtable *rt = ip_route_output_key(geneve->net, &fl4);
c40e89fd35 Alexey Kodanev 2018-04-19 1506
c40e89fd35 Alexey Kodanev 2018-04-19 1507 if (!IS_ERR(rt) && rt->dst.dev) {
c40e89fd35 Alexey Kodanev 2018-04-19 1508 ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV4_HLEN;
c40e89fd35 Alexey Kodanev 2018-04-19 1509 ip_rt_put(rt);
c40e89fd35 Alexey Kodanev 2018-04-19 1510 }
c40e89fd35 Alexey Kodanev 2018-04-19 1511 break;
c40e89fd35 Alexey Kodanev 2018-04-19 1512 }
c40e89fd35 Alexey Kodanev 2018-04-19 1513 #if IS_ENABLED(CONFIG_IPV6)
c40e89fd35 Alexey Kodanev 2018-04-19 1514 case AF_INET6: {
55e942d018 Hangbin Liu 2019-02-06 1515 struct inet6_dev *idev = in6_dev_get(dev);
55e942d018 Hangbin Liu 2019-02-06 1516 if (!idev)
55e942d018 Hangbin Liu 2019-02-06 1517 break;
55e942d018 Hangbin Liu 2019-02-06 1518
c40e89fd35 Alexey Kodanev 2018-04-19 @1519 struct rt6_info *rt = rt6_lookup(geneve->net,
c40e89fd35 Alexey Kodanev 2018-04-19 1520 &info->key.u.ipv6.dst, NULL, 0,
c40e89fd35 Alexey Kodanev 2018-04-19 1521 NULL, 0);
c40e89fd35 Alexey Kodanev 2018-04-19 1522
c40e89fd35 Alexey Kodanev 2018-04-19 1523 if (rt && rt->dst.dev)
c40e89fd35 Alexey Kodanev 2018-04-19 1524 ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
c40e89fd35 Alexey Kodanev 2018-04-19 1525 ip6_rt_put(rt);
55e942d018 Hangbin Liu 2019-02-06 1526
55e942d018 Hangbin Liu 2019-02-06 1527 in6_dev_put(idev);
c40e89fd35 Alexey Kodanev 2018-04-19 1528 break;
c40e89fd35 Alexey Kodanev 2018-04-19 1529 }
c40e89fd35 Alexey Kodanev 2018-04-19 1530 #endif
c40e89fd35 Alexey Kodanev 2018-04-19 1531 }
c40e89fd35 Alexey Kodanev 2018-04-19 1532
c40e89fd35 Alexey Kodanev 2018-04-19 1533 if (ldev_mtu <= 0)
c40e89fd35 Alexey Kodanev 2018-04-19 1534 return;
c40e89fd35 Alexey Kodanev 2018-04-19 1535
c40e89fd35 Alexey Kodanev 2018-04-19 1536 geneve_change_mtu(dev, ldev_mtu - info->options_len);
c40e89fd35 Alexey Kodanev 2018-04-19 1537 }
c40e89fd35 Alexey Kodanev 2018-04-19 1538
:::::: The code at line 1519 was first introduced by commit
:::::: c40e89fd358e94a55d6c1475afbea17b5580f601 geneve: configure MTU based on a lower device
:::::: TO: Alexey Kodanev <alexey.kodanev@oracle.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 12117 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up
2019-02-06 12:51 [PATCH net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-06 12:51 ` [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach() Hangbin Liu
@ 2019-02-07 10:36 ` Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
` (2 more replies)
2 siblings, 3 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-07 10:36 UTC (permalink / raw)
To: netdev; +Cc: Stefano Brivio, David Miller, Eric Dumazet, Hangbin Liu
When disabled IPv6 on boot up, since there is no ipv6 route tables, we should
not call rt6_lookup. Fix them by checking if we have inet6_dev pointer on
netdevice.
v2: Fix idev reference leak, declarations and code mixing as Stefano,
Eric pointed. Since we only want to check if idev exists and not
reference it, use __in6_dev_get() insteand of in6_dev_get().
Hangbin Liu (2):
geneve: should not call rt6_lookup() when ipv6 was disabled
sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach()
drivers/net/geneve.c | 6 ++++++
net/ipv6/sit.c | 8 +++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
--
2.19.2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
@ 2019-02-07 10:36 ` Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 2/2] sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach() Hangbin Liu
2019-02-07 18:48 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up David Miller
2 siblings, 0 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-07 10:36 UTC (permalink / raw)
To: netdev
Cc: Stefano Brivio, David Miller, Eric Dumazet, Hangbin Liu, Alexey Kodanev
When we add a new GENEVE device with IPv6 remote, checking only for
IS_ENABLED(CONFIG_IPV6) is not enough as we may disable IPv6 in the
kernel command line (ipv6.disable=1), and calling rt6_lookup() would
cause a NULL pointer dereference.
v2:
- don't mix declarations and code (reported by Stefano Brivio, Eric Dumazet)
- there's no need to use in6_dev_get() as we only need to check that
idev exists (reported by David Ahern). This is under RTNL, so we can
simply use __in6_dev_get() instead (Stefano, Eric).
Reported-by: Jianlin Shi <jishi@redhat.com>
Fixes: c40e89fd358e9 ("geneve: configure MTU based on a lower device")
Cc: Alexey Kodanev <alexey.kodanev@oracle.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
---
drivers/net/geneve.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 58bbba8582b0..3377ac66a347 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1512,9 +1512,13 @@ static void geneve_link_config(struct net_device *dev,
}
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6: {
- struct rt6_info *rt = rt6_lookup(geneve->net,
- &info->key.u.ipv6.dst, NULL, 0,
- NULL, 0);
+ struct rt6_info *rt;
+
+ if (!__in6_dev_get(dev))
+ break;
+
+ rt = rt6_lookup(geneve->net, &info->key.u.ipv6.dst, NULL, 0,
+ NULL, 0);
if (rt && rt->dst.dev)
ldev_mtu = rt->dst.dev->mtu - GENEVE_IPV6_HLEN;
--
2.19.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 net 2/2] sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach()
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
@ 2019-02-07 10:36 ` Hangbin Liu
2019-02-07 18:48 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up David Miller
2 siblings, 0 replies; 16+ messages in thread
From: Hangbin Liu @ 2019-02-07 10:36 UTC (permalink / raw)
To: netdev
Cc: Stefano Brivio, David Miller, Eric Dumazet, Hangbin Liu, Oussama Ghorbel
If we disabled IPv6 from the kernel command line (ipv6.disable=1), we should
not call ip6_err_gen_icmpv6_unreach(). This:
ip link add sit1 type sit local 192.0.2.1 remote 192.0.2.2 ttl 1
ip link set sit1 up
ip addr add 198.51.100.1/24 dev sit1
ping 198.51.100.2
if IPv6 is disabled at boot time, will crash the kernel.
v2: there's no need to use in6_dev_get(), use __in6_dev_get() instead,
as we only need to check that idev exists and we are under
rcu_read_lock() (from netif_receive_skb_internal()).
Reported-by: Jianlin Shi <jishi@redhat.com>
Fixes: ca15a078bd90 ("sit: generate icmpv6 error when receiving icmpv4 error")
Cc: Oussama Ghorbel <ghorbel@pivasoftware.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
---
net/ipv6/sit.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1e03305c0549..e8a1dabef803 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -546,7 +546,8 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
}
err = 0;
- if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
+ if (__in6_dev_get(skb->dev) &&
+ !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
goto out;
if (t->parms.iph.daddr == 0)
--
2.19.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 2/2] sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach() Hangbin Liu
@ 2019-02-07 18:48 ` David Miller
2 siblings, 0 replies; 16+ messages in thread
From: David Miller @ 2019-02-07 18:48 UTC (permalink / raw)
To: liuhangbin; +Cc: netdev, sbrivio, eric.dumazet
From: Hangbin Liu <liuhangbin@gmail.com>
Date: Thu, 7 Feb 2019 18:36:09 +0800
> When disabled IPv6 on boot up, since there is no ipv6 route tables, we should
> not call rt6_lookup. Fix them by checking if we have inet6_dev pointer on
> netdevice.
>
> v2: Fix idev reference leak, declarations and code mixing as Stefano,
> Eric pointed. Since we only want to check if idev exists and not
> reference it, use __in6_dev_get() insteand of in6_dev_get().
Series applied and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2019-02-07 18:49 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-06 12:51 [PATCH net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-06 12:51 ` [PATCH net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-06 14:58 ` Stefano Brivio
2019-02-06 16:43 ` Eric Dumazet
2019-02-06 18:54 ` David Ahern
2019-02-06 19:04 ` Stefano Brivio
2019-02-06 19:09 ` Eric Dumazet
2019-02-06 19:08 ` Eric Dumazet
2019-02-07 0:55 ` kbuild test robot
2019-02-06 12:51 ` [PATCH net 2/2] sit: check if IPv6 enabled before call ip6_err_gen_icmpv6_unreach() Hangbin Liu
2019-02-06 15:00 ` Stefano Brivio
2019-02-06 16:45 ` Eric Dumazet
2019-02-07 10:36 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 1/2] geneve: should not call rt6_lookup() when ipv6 was disabled Hangbin Liu
2019-02-07 10:36 ` [PATCH v2 net 2/2] sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach() Hangbin Liu
2019-02-07 18:48 ` [PATCH v2 net 0/2] fix two kernel panics when disabled IPv6 on boot up David Miller
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).