bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs
@ 2021-03-10  0:38 Daniel Borkmann
  2021-03-10  0:38 ` [PATCH net 1/2] net: Consolidate common blackhole dst ops Daniel Borkmann
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-03-10  0:38 UTC (permalink / raw)
  To: davem
  Cc: kuba, john.fastabend, ast, willemb, edumazet, netdev, bpf,
	Daniel Borkmann

Fix a NULL pointer deref panic I ran into for regular ip6ip6 tunnel devices
when collect_md populated skbs were redirected to them for xmit. See patches
for further details, thanks!

Daniel Borkmann (2):
  net: Consolidate common blackhole dst ops
  net, bpf: Fix ip6ip6 crash with collect_md populated skbs

 include/net/dst.h | 11 +++++++++
 net/core/dst.c    | 59 +++++++++++++++++++++++++++++++++--------------
 net/ipv4/route.c  | 45 +++++++-----------------------------
 net/ipv6/route.c  | 36 ++++++++---------------------
 4 files changed, 70 insertions(+), 81 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net 1/2] net: Consolidate common blackhole dst ops
  2021-03-10  0:38 [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs Daniel Borkmann
@ 2021-03-10  0:38 ` Daniel Borkmann
  2021-03-10  0:38 ` [PATCH net 2/2] net, bpf: Fix ip6ip6 crash with collect_md populated skbs Daniel Borkmann
  2021-03-10 20:40 ` [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-03-10  0:38 UTC (permalink / raw)
  To: davem
  Cc: kuba, john.fastabend, ast, willemb, edumazet, netdev, bpf,
	Daniel Borkmann

Move generic blackhole dst ops to the core and use them from both
ipv4_dst_blackhole_ops and ip6_dst_blackhole_ops where possible. No
functional change otherwise. We need these also in other locations
and having to define them over and over again is not great.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 include/net/dst.h | 11 +++++++++++
 net/core/dst.c    | 38 ++++++++++++++++++++++++++++++++++++++
 net/ipv4/route.c  | 45 ++++++++-------------------------------------
 net/ipv6/route.c  | 36 +++++++++---------------------------
 4 files changed, 66 insertions(+), 64 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 26f134ad3a25..75b1e734e9c2 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -550,4 +550,15 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu)
 		dst->ops->update_pmtu(dst, NULL, skb, mtu, false);
 }
 
+struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie);
+void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
+			       struct sk_buff *skb, u32 mtu, bool confirm_neigh);
+void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
+			    struct sk_buff *skb);
+u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old);
+struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst,
+					     struct sk_buff *skb,
+					     const void *daddr);
+unsigned int dst_blackhole_mtu(const struct dst_entry *dst);
+
 #endif /* _NET_DST_H */
diff --git a/net/core/dst.c b/net/core/dst.c
index 0c01bd8d9d81..5f6315601776 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -237,6 +237,44 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old)
 }
 EXPORT_SYMBOL(__dst_destroy_metrics_generic);
 
+struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie)
+{
+	return NULL;
+}
+
+u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old)
+{
+	return NULL;
+}
+
+struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst,
+					     struct sk_buff *skb,
+					     const void *daddr)
+{
+	return NULL;
+}
+
+void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
+			       struct sk_buff *skb, u32 mtu,
+			       bool confirm_neigh)
+{
+}
+EXPORT_SYMBOL_GPL(dst_blackhole_update_pmtu);
+
+void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
+			    struct sk_buff *skb)
+{
+}
+EXPORT_SYMBOL_GPL(dst_blackhole_redirect);
+
+unsigned int dst_blackhole_mtu(const struct dst_entry *dst)
+{
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	return mtu ? : dst->dev->mtu;
+}
+EXPORT_SYMBOL_GPL(dst_blackhole_mtu);
+
 static struct dst_ops md_dst_ops = {
 	.family =		AF_UNSPEC,
 };
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 02d81d79deeb..bba150fdd265 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2687,44 +2687,15 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4,
 	return rth;
 }
 
-static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie)
-{
-	return NULL;
-}
-
-static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst)
-{
-	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
-
-	return mtu ? : dst->dev->mtu;
-}
-
-static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
-					  struct sk_buff *skb, u32 mtu,
-					  bool confirm_neigh)
-{
-}
-
-static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
-				       struct sk_buff *skb)
-{
-}
-
-static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst,
-					  unsigned long old)
-{
-	return NULL;
-}
-
 static struct dst_ops ipv4_dst_blackhole_ops = {
-	.family			=	AF_INET,
-	.check			=	ipv4_blackhole_dst_check,
-	.mtu			=	ipv4_blackhole_mtu,
-	.default_advmss		=	ipv4_default_advmss,
-	.update_pmtu		=	ipv4_rt_blackhole_update_pmtu,
-	.redirect		=	ipv4_rt_blackhole_redirect,
-	.cow_metrics		=	ipv4_rt_blackhole_cow_metrics,
-	.neigh_lookup		=	ipv4_neigh_lookup,
+	.family			= AF_INET,
+	.default_advmss		= ipv4_default_advmss,
+	.neigh_lookup		= ipv4_neigh_lookup,
+	.check			= dst_blackhole_check,
+	.cow_metrics		= dst_blackhole_cow_metrics,
+	.update_pmtu		= dst_blackhole_update_pmtu,
+	.redirect		= dst_blackhole_redirect,
+	.mtu			= dst_blackhole_mtu,
 };
 
 struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1536f4948e86..1056b0229ffd 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -260,34 +260,16 @@ static struct dst_ops ip6_dst_ops_template = {
 	.confirm_neigh		=	ip6_confirm_neigh,
 };
 
-static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
-{
-	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
-
-	return mtu ? : dst->dev->mtu;
-}
-
-static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
-					 struct sk_buff *skb, u32 mtu,
-					 bool confirm_neigh)
-{
-}
-
-static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
-				      struct sk_buff *skb)
-{
-}
-
 static struct dst_ops ip6_dst_blackhole_ops = {
-	.family			=	AF_INET6,
-	.destroy		=	ip6_dst_destroy,
-	.check			=	ip6_dst_check,
-	.mtu			=	ip6_blackhole_mtu,
-	.default_advmss		=	ip6_default_advmss,
-	.update_pmtu		=	ip6_rt_blackhole_update_pmtu,
-	.redirect		=	ip6_rt_blackhole_redirect,
-	.cow_metrics		=	dst_cow_metrics_generic,
-	.neigh_lookup		=	ip6_dst_neigh_lookup,
+	.family			= AF_INET6,
+	.default_advmss		= ip6_default_advmss,
+	.neigh_lookup		= ip6_dst_neigh_lookup,
+	.check			= ip6_dst_check,
+	.destroy		= ip6_dst_destroy,
+	.cow_metrics		= dst_cow_metrics_generic,
+	.update_pmtu		= dst_blackhole_update_pmtu,
+	.redirect		= dst_blackhole_redirect,
+	.mtu			= dst_blackhole_mtu,
 };
 
 static const u32 ip6_template_metrics[RTAX_MAX] = {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH net 2/2] net, bpf: Fix ip6ip6 crash with collect_md populated skbs
  2021-03-10  0:38 [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs Daniel Borkmann
  2021-03-10  0:38 ` [PATCH net 1/2] net: Consolidate common blackhole dst ops Daniel Borkmann
@ 2021-03-10  0:38 ` Daniel Borkmann
  2021-03-10 20:40 ` [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-03-10  0:38 UTC (permalink / raw)
  To: davem
  Cc: kuba, john.fastabend, ast, willemb, edumazet, netdev, bpf,
	Daniel Borkmann

I ran into a crash where setting up a ip6ip6 tunnel device which was /not/
set to collect_md mode was receiving collect_md populated skbs for xmit.

The BPF prog was populating the skb via bpf_skb_set_tunnel_key() which is
assigning special metadata dst entry and then redirecting the skb to the
device, taking ip6_tnl_start_xmit() -> ipxip6_tnl_xmit() -> ip6_tnl_xmit()
and in the latter it performs a neigh lookup based on skb_dst(skb) where
we trigger a NULL pointer dereference on dst->ops->neigh_lookup() since
the md_dst_ops do not populate neigh_lookup callback with a fake handler.

Transform the md_dst_ops into generic dst_blackhole_ops that can also be
reused elsewhere when needed, and use them for the metadata dst entries as
callback ops.

Also, remove the dst_md_discard{,_out}() ops and rely on dst_discard{,_out}()
from dst_init() which free the skb the same way modulo the splat. Given we
will be able to recover just fine from there, avoid any potential splats
iff this gets ever triggered in future (or worse, panic on warns when set).

Fixes: f38a9eb1f77b ("dst: Metadata destinations")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
 net/core/dst.c | 31 +++++++++----------------------
 1 file changed, 9 insertions(+), 22 deletions(-)

diff --git a/net/core/dst.c b/net/core/dst.c
index 5f6315601776..fb3bcba87744 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -275,37 +275,24 @@ unsigned int dst_blackhole_mtu(const struct dst_entry *dst)
 }
 EXPORT_SYMBOL_GPL(dst_blackhole_mtu);
 
-static struct dst_ops md_dst_ops = {
-	.family =		AF_UNSPEC,
+static struct dst_ops dst_blackhole_ops = {
+	.family		= AF_UNSPEC,
+	.neigh_lookup	= dst_blackhole_neigh_lookup,
+	.check		= dst_blackhole_check,
+	.cow_metrics	= dst_blackhole_cow_metrics,
+	.update_pmtu	= dst_blackhole_update_pmtu,
+	.redirect	= dst_blackhole_redirect,
+	.mtu		= dst_blackhole_mtu,
 };
 
-static int dst_md_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	WARN_ONCE(1, "Attempting to call output on metadata dst\n");
-	kfree_skb(skb);
-	return 0;
-}
-
-static int dst_md_discard(struct sk_buff *skb)
-{
-	WARN_ONCE(1, "Attempting to call input on metadata dst\n");
-	kfree_skb(skb);
-	return 0;
-}
-
 static void __metadata_dst_init(struct metadata_dst *md_dst,
 				enum metadata_type type, u8 optslen)
-
 {
 	struct dst_entry *dst;
 
 	dst = &md_dst->dst;
-	dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE,
+	dst_init(dst, &dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE,
 		 DST_METADATA | DST_NOCOUNT);
-
-	dst->input = dst_md_discard;
-	dst->output = dst_md_discard_out;
-
 	memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst));
 	md_dst->type = type;
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs
  2021-03-10  0:38 [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs Daniel Borkmann
  2021-03-10  0:38 ` [PATCH net 1/2] net: Consolidate common blackhole dst ops Daniel Borkmann
  2021-03-10  0:38 ` [PATCH net 2/2] net, bpf: Fix ip6ip6 crash with collect_md populated skbs Daniel Borkmann
@ 2021-03-10 20:40 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-03-10 20:40 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: davem, kuba, john.fastabend, ast, willemb, edumazet, netdev, bpf

Hello:

This series was applied to netdev/net.git (refs/heads/master):

On Wed, 10 Mar 2021 01:38:08 +0100 you wrote:
> Fix a NULL pointer deref panic I ran into for regular ip6ip6 tunnel devices
> when collect_md populated skbs were redirected to them for xmit. See patches
> for further details, thanks!
> 
> Daniel Borkmann (2):
>   net: Consolidate common blackhole dst ops
>   net, bpf: Fix ip6ip6 crash with collect_md populated skbs
> 
> [...]

Here is the summary with links:
  - [net,1/2] net: Consolidate common blackhole dst ops
    https://git.kernel.org/netdev/net/c/c4c877b27324
  - [net,2/2] net, bpf: Fix ip6ip6 crash with collect_md populated skbs
    https://git.kernel.org/netdev/net/c/a188bb5638d4

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-03-10 20:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-10  0:38 [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs Daniel Borkmann
2021-03-10  0:38 ` [PATCH net 1/2] net: Consolidate common blackhole dst ops Daniel Borkmann
2021-03-10  0:38 ` [PATCH net 2/2] net, bpf: Fix ip6ip6 crash with collect_md populated skbs Daniel Borkmann
2021-03-10 20:40 ` [PATCH net 0/2] Fix ip6ip6 crash for collect_md skbs patchwork-bot+netdevbpf

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).