From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexander Duyck Subject: [net-next PATCH v2] udp: Resolve NULL pointer dereference over flow-based vxlan device Date: Thu, 12 May 2016 12:51:02 -0700 Message-ID: <20160512195003.26694.17950.stgit@localhost.localdomain> References: <20160512022306.3691.40769.stgit@localhost.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Cc: tgraf@suug.ch, tom@herbertland.com, jbenc@redhat.com, eric.dumazet@gmail.com To: netdev@vger.kernel.org, davem@davemloft.net, alexander.duyck@gmail.com Return-path: Received: from mail-pf0-f173.google.com ([209.85.192.173]:35242 "EHLO mail-pf0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752978AbcELTvI (ORCPT ); Thu, 12 May 2016 15:51:08 -0400 Received: by mail-pf0-f173.google.com with SMTP id 77so33781860pfv.2 for ; Thu, 12 May 2016 12:51:07 -0700 (PDT) In-Reply-To: <20160512022306.3691.40769.stgit@localhost.localdomain> Sender: netdev-owner@vger.kernel.org List-ID: While testing an OpenStack configuration using VXLANs I saw the following call trace: RIP: 0010:[] udp4_lib_lookup_skb+0x49/0x80 RSP: 0018:ffff88103867bc50 EFLAGS: 00010286 RAX: ffff88103269bf00 RBX: ffff88103269bf00 RCX: 00000000ffffffff RDX: 0000000000004300 RSI: 0000000000000000 RDI: ffff880f2932e780 RBP: ffff88103867bc60 R08: 0000000000000000 R09: 000000009001a8c0 R10: 0000000000004400 R11: ffffffff81333a58 R12: ffff880f2932e794 R13: 0000000000000014 R14: 0000000000000014 R15: ffffe8efbfd89ca0 FS: 0000000000000000(0000) GS:ffff88103fd80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000488 CR3: 0000000001c06000 CR4: 00000000001426e0 Stack: ffffffff81576515 ffffffff815733c0 ffff88103867bc98 ffffffff815fcc17 ffff88103269bf00 ffffe8efbfd89ca0 0000000000000014 0000000000000080 ffffe8efbfd89ca0 ffff88103867bcc8 ffffffff815fcf8b ffff880f2932e794 Call Trace: [] ? skb_checksum+0x35/0x50 [] ? skb_push+0x40/0x40 [] udp_gro_receive+0x57/0x130 [] udp4_gro_receive+0x10b/0x2c0 [] inet_gro_receive+0x1d3/0x270 [] dev_gro_receive+0x269/0x3b0 [] napi_gro_receive+0x38/0x120 [] gro_cell_poll+0x57/0x80 [vxlan] [] net_rx_action+0x160/0x380 [] __do_softirq+0xd7/0x2c5 [] run_ksoftirqd+0x29/0x50 [] smpboot_thread_fn+0x10f/0x160 [] ? sort_range+0x30/0x30 [] kthread+0xd8/0xf0 [] ret_from_fork+0x22/0x40 [] ? kthread_park+0x60/0x60 The following trace is seen when receiving a DHCP request over a flow-based VXLAN tunnel. I believe this is caused by the metadata dst having a NULL dev value and as a result dev_net(dev) is causing a NULL pointer dereference. To resolve this I am replacing the check for skb_dst() with skb_valid_dst() so that we do not attempt to use the metadata dst to retrieve a device in order to determine the network namespace. Fixes: 63058308cd55 ("udp: Add udp6_lib_lookup_skb and udp4_lib_lookup_skb") Signed-off-by: Alexander Duyck --- net/ipv4/udp.c | 3 ++- net/ipv6/udp.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f67f52ba4809..69aa7ab81933 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -114,6 +114,7 @@ #include #include "udp_impl.h" #include +#include struct udp_table udp_table __read_mostly; EXPORT_SYMBOL(udp_table); @@ -614,7 +615,7 @@ struct sock *udp4_lib_lookup_skb(struct sk_buff *skb, { const struct iphdr *iph = ip_hdr(skb); const struct net_device *dev = - skb_dst(skb) ? skb_dst(skb)->dev : skb->dev; + skb_valid_dst(skb) ? skb_dst(skb)->dev : skb->dev; return __udp4_lib_lookup(dev_net(dev), iph->saddr, sport, iph->daddr, dport, inet_iif(skb), diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index aca06094110f..12c06deda5ef 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -331,7 +332,7 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, { const struct ipv6hdr *iph = ipv6_hdr(skb); const struct net_device *dev = - skb_dst(skb) ? skb_dst(skb)->dev : skb->dev; + skb_valid_dst(skb) ? skb_dst(skb)->dev : skb->dev; return __udp6_lib_lookup(dev_net(dev), &iph->saddr, sport, &iph->daddr, dport, inet6_iif(skb),