netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).