Patch "net, bpf: Fix ip6ip6 crash with collect_md populated skbs" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net, bpf: Fix ip6ip6 crash with collect_md populated skbs

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-bpf-fix-ip6ip6-crash-with-collect_md-populated-s.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 89ea5a5f2609c184c85f89dfd2b84cafac93f5c0
Author: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
Date:   Wed Mar 10 01:38:10 2021 +0100

    net, bpf: Fix ip6ip6 crash with collect_md populated skbs
    
    [ Upstream commit a188bb5638d41aa99090ebf2f85d3505ab13fba5 ]
    
    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@xxxxxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

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;
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux