Patch "ipv4: tcp: send zero IPID in SYNACK messages" has been added to the 5.15-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

    ipv4: tcp: send zero IPID in SYNACK messages

to the 5.15-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:
     ipv4-tcp-send-zero-ipid-in-synack-messages.patch
and it can be found in the queue-5.15 subdirectory.

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



commit abb13d51a34851d59167b049b5ede236e300336f
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Wed Jan 26 17:10:21 2022 -0800

    ipv4: tcp: send zero IPID in SYNACK messages
    
    [ Upstream commit 970a5a3ea86da637471d3cd04d513a0755aba4bf ]
    
    In commit 431280eebed9 ("ipv4: tcp: send zero IPID for RST and
    ACK sent in SYN-RECV and TIME-WAIT state") we took care of some
    ctl packets sent by TCP.
    
    It turns out we need to use a similar strategy for SYNACK packets.
    
    By default, they carry IP_DF and IPID==0, but there are ways
    to ask them to use the hashed IP ident generator and thus
    be used to build off-path attacks.
    (Ref: Off-Path TCP Exploits of the Mixed IPID Assignment)
    
    One of this way is to force (before listener is started)
    echo 1 >/proc/sys/net/ipv4/ip_no_pmtu_disc
    
    Another way is using forged ICMP ICMP_FRAG_NEEDED
    with a very small MTU (like 68) to force a false return from
    ip_dont_fragment()
    
    In this patch, ip_build_and_send_pkt() uses the following
    heuristics.
    
    1) Most SYNACK packets are smaller than IPV4_MIN_MTU and therefore
    can use IP_DF regardless of the listener or route pmtu setting.
    
    2) In case the SYNACK packet is bigger than IPV4_MIN_MTU,
    we use prandom_u32() generator instead of the IPv4 hashed ident one.
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Reported-by: Ray Che <xijiache@xxxxxxxxx>
    Reviewed-by: David Ahern <dsahern@xxxxxxxxxx>
    Cc: Geoff Alexander <alexandg@xxxxxxxxxx>
    Cc: Willy Tarreau <w@xxxxxx>
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ff38b46bd4b0f..a4d2eb691cbc1 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -162,12 +162,19 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
 	iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
 	iph->saddr    = saddr;
 	iph->protocol = sk->sk_protocol;
-	if (ip_dont_fragment(sk, &rt->dst)) {
+	/* Do not bother generating IPID for small packets (eg SYNACK) */
+	if (skb->len <= IPV4_MIN_MTU || ip_dont_fragment(sk, &rt->dst)) {
 		iph->frag_off = htons(IP_DF);
 		iph->id = 0;
 	} else {
 		iph->frag_off = 0;
-		__ip_select_ident(net, iph, 1);
+		/* TCP packets here are SYNACK with fat IPv4/TCP options.
+		 * Avoid using the hashed IP ident generator.
+		 */
+		if (sk->sk_protocol == IPPROTO_TCP)
+			iph->id = (__force __be16)prandom_u32();
+		else
+			__ip_select_ident(net, iph, 1);
 	}
 
 	if (opt && opt->opt.optlen) {



[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