Patch "ip6_gre: Fix skb_under_panic in __gre6_xmit()" has been added to the 4.19-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

    ip6_gre: Fix skb_under_panic in __gre6_xmit()

to the 4.19-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:
     ip6_gre-fix-skb_under_panic-in-__gre6_xmit.patch
and it can be found in the queue-4.19 subdirectory.

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



commit bd2b9ccddda249bdb6bfadd142b587bac1c0cf64
Author: Peilin Ye <peilin.ye@xxxxxxxxxxxxx>
Date:   Thu Apr 14 13:35:40 2022 -0700

    ip6_gre: Fix skb_under_panic in __gre6_xmit()
    
    [ Upstream commit ab198e1d0dd8dc4bc7575fb50758e2cbd51e14e1 ]
    
    Feng reported an skb_under_panic BUG triggered by running
    test_ip6gretap() in tools/testing/selftests/bpf/test_tunnel.sh:
    
    [   82.492551] skbuff: skb_under_panic: text:ffffffffb268bb8e len:403 put:12 head:ffff9997c5480000 data:ffff9997c547fff8 tail:0x18b end:0x2c0 dev:ip6gretap11
    <...>
    [   82.607380] Call Trace:
    [   82.609389]  <TASK>
    [   82.611136]  skb_push.cold.109+0x10/0x10
    [   82.614289]  __gre6_xmit+0x41e/0x590
    [   82.617169]  ip6gre_tunnel_xmit+0x344/0x3f0
    [   82.620526]  dev_hard_start_xmit+0xf1/0x330
    [   82.623882]  sch_direct_xmit+0xe4/0x250
    [   82.626961]  __dev_queue_xmit+0x720/0xfe0
    <...>
    [   82.633431]  packet_sendmsg+0x96a/0x1cb0
    [   82.636568]  sock_sendmsg+0x30/0x40
    <...>
    
    The following sequence of events caused the BUG:
    
    1. During ip6gretap device initialization, tunnel->tun_hlen (e.g. 4) is
       calculated based on old flags (see ip6gre_calc_hlen());
    2. packet_snd() reserves header room for skb A, assuming
       tunnel->tun_hlen is 4;
    3. Later (in clsact Qdisc), the eBPF program sets a new tunnel key for
       skb A using bpf_skb_set_tunnel_key() (see _ip6gretap_set_tunnel());
    4. __gre6_xmit() detects the new tunnel key, and recalculates
       "tun_hlen" (e.g. 12) based on new flags (e.g. TUNNEL_KEY and
       TUNNEL_SEQ);
    5. gre_build_header() calls skb_push() with insufficient reserved header
       room, triggering the BUG.
    
    As sugguested by Cong, fix it by moving the call to skb_cow_head() after
    the recalculation of tun_hlen.
    
    Reproducer:
    
      OBJ=$LINUX/tools/testing/selftests/bpf/test_tunnel_kern.o
    
      ip netns add at_ns0
      ip link add veth0 type veth peer name veth1
      ip link set veth0 netns at_ns0
      ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
      ip netns exec at_ns0 ip link set dev veth0 up
      ip link set dev veth1 up mtu 1500
      ip addr add dev veth1 172.16.1.200/24
    
      ip netns exec at_ns0 ip addr add ::11/96 dev veth0
      ip netns exec at_ns0 ip link set dev veth0 up
      ip addr add dev veth1 ::22/96
      ip link set dev veth1 up
    
      ip netns exec at_ns0 \
            ip link add dev ip6gretap00 type ip6gretap seq flowlabel 0xbcdef key 2 \
            local ::11 remote ::22
    
      ip netns exec at_ns0 ip addr add dev ip6gretap00 10.1.1.100/24
      ip netns exec at_ns0 ip addr add dev ip6gretap00 fc80::100/96
      ip netns exec at_ns0 ip link set dev ip6gretap00 up
    
      ip link add dev ip6gretap11 type ip6gretap external
      ip addr add dev ip6gretap11 10.1.1.200/24
      ip addr add dev ip6gretap11 fc80::200/24
      ip link set dev ip6gretap11 up
    
      tc qdisc add dev ip6gretap11 clsact
      tc filter add dev ip6gretap11 egress bpf da obj $OBJ sec ip6gretap_set_tunnel
      tc filter add dev ip6gretap11 ingress bpf da obj $OBJ sec ip6gretap_get_tunnel
    
      ping6 -c 3 -w 10 -q ::11
    
    Fixes: 6712abc168eb ("ip6_gre: add ip6 gre and gretap collect_md mode")
    Reported-by: Feng Zhou <zhoufeng.zf@xxxxxxxxxxxxx>
    Co-developed-by: Cong Wang <cong.wang@xxxxxxxxxxxxx>
    Signed-off-by: Cong Wang <cong.wang@xxxxxxxxxxxxx>
    Signed-off-by: Peilin Ye <peilin.ye@xxxxxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 166b7544e54a4..17765865cb536 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -740,9 +740,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
 	else
 		fl6->daddr = tunnel->parms.raddr;
 
-	if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen))
-		return -ENOMEM;
-
 	/* Push GRE header. */
 	protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
 
@@ -770,6 +767,9 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
 			(TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
 		tun_hlen = gre_calc_hlen(flags);
 
+		if (skb_cow_head(skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_hlen))
+			return -ENOMEM;
+
 		gre_build_header(skb, tun_hlen,
 				 flags, protocol,
 				 tunnel_id_to_key32(tun_info->key.tun_id),
@@ -780,6 +780,9 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
 		if (tunnel->parms.o_flags & TUNNEL_SEQ)
 			tunnel->o_seqno++;
 
+		if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen))
+			return -ENOMEM;
+
 		gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
 				 protocol, tunnel->parms.o_key,
 				 htonl(tunnel->o_seqno));



[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