From a5f41287571578b62106f8ea4b25edbeda4512bf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 Jun 2024 17:44:22 +0200 Subject: [PATCH] 6.9-stable patches added patches: tcp-reduce-accepted-window-in-new_syn_recv-state.patch --- queue-6.9/series | 1 + ...ccepted-window-in-new_syn_recv-state.patch | 111 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 queue-6.9/tcp-reduce-accepted-window-in-new_syn_recv-state.patch diff --git a/queue-6.9/series b/queue-6.9/series index 64ad140a8c7..f91396973c2 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -279,3 +279,4 @@ cifs-set-zero_point-in-the-copy_file_range-and-remap.patch cifs-fix-missing-set-of-remote_i_size.patch tracing-probes-fix-error-check-in-parse_btf_field.patch tpm_tis_spi-account-for-spi-header-when-allocating-t.patch +tcp-reduce-accepted-window-in-new_syn_recv-state.patch diff --git a/queue-6.9/tcp-reduce-accepted-window-in-new_syn_recv-state.patch b/queue-6.9/tcp-reduce-accepted-window-in-new_syn_recv-state.patch new file mode 100644 index 00000000000..12252c2b233 --- /dev/null +++ b/queue-6.9/tcp-reduce-accepted-window-in-new_syn_recv-state.patch @@ -0,0 +1,111 @@ +From f4dca95fc0f6350918f2e6727e35b41f7f86fcce Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 23 May 2024 13:05:27 +0000 +Subject: tcp: reduce accepted window in NEW_SYN_RECV state + +From: Eric Dumazet + +commit f4dca95fc0f6350918f2e6727e35b41f7f86fcce upstream. + +Jason commit made checks against ACK sequence less strict +and can be exploited by attackers to establish spoofed flows +with less probes. + +Innocent users might use tcp_rmem[1] == 1,000,000,000, +or something more reasonable. + +An attacker can use a regular TCP connection to learn the server +initial tp->rcv_wnd, and use it to optimize the attack. + +If we make sure that only the announced window (smaller than 65535) +is used for ACK validation, we force an attacker to use +65537 packets to complete the 3WHS (assuming server ISN is unknown) + +Fixes: 378979e94e95 ("tcp: remove 64 KByte limit for initial tp->rcv_wnd value") +Link: https://datatracker.ietf.org/meeting/119/materials/slides-119-tcpm-ghost-acks-00 +Signed-off-by: Eric Dumazet +Acked-by: Neal Cardwell +Reviewed-by: Jason Xing +Link: https://lore.kernel.org/r/20240523130528.60376-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Cc: Holger Hoffstätte +Signed-off-by: Greg Kroah-Hartman +--- + include/net/request_sock.h | 12 ++++++++++++ + net/ipv4/tcp_ipv4.c | 7 +------ + net/ipv4/tcp_minisocks.c | 7 +++++-- + net/ipv6/tcp_ipv6.c | 7 +------ + 4 files changed, 19 insertions(+), 14 deletions(-) + +--- a/include/net/request_sock.h ++++ b/include/net/request_sock.h +@@ -282,4 +282,16 @@ static inline int reqsk_queue_len_young( + return atomic_read(&queue->young); + } + ++/* RFC 7323 2.3 Using the Window Scale Option ++ * The window field (SEG.WND) of every outgoing segment, with the ++ * exception of segments, MUST be right-shifted by ++ * Rcv.Wind.Shift bits. ++ * ++ * This means the SEG.WND carried in SYNACK can not exceed 65535. ++ * We use this property to harden TCP stack while in NEW_SYN_RECV state. ++ */ ++static inline u32 tcp_synack_window(const struct request_sock *req) ++{ ++ return min(req->rsk_rcv_wnd, 65535U); ++} + #endif /* _REQUEST_SOCK_H */ +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -1143,14 +1143,9 @@ static void tcp_v4_reqsk_send_ack(const + #endif + } + +- /* RFC 7323 2.3 +- * The window field (SEG.WND) of every outgoing segment, with the +- * exception of segments, MUST be right-shifted by +- * Rcv.Wind.Shift bits: +- */ + tcp_v4_send_ack(sk, skb, seq, + tcp_rsk(req)->rcv_nxt, +- req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, ++ tcp_synack_window(req) >> inet_rsk(req)->rcv_wscale, + tcp_rsk_tsval(tcp_rsk(req)), + READ_ONCE(req->ts_recent), + 0, &key, +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -783,8 +783,11 @@ struct sock *tcp_check_req(struct sock * + + /* RFC793: "first check sequence number". */ + +- if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, +- tcp_rsk(req)->rcv_nxt, tcp_rsk(req)->rcv_nxt + req->rsk_rcv_wnd)) { ++ if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, ++ TCP_SKB_CB(skb)->end_seq, ++ tcp_rsk(req)->rcv_nxt, ++ tcp_rsk(req)->rcv_nxt + ++ tcp_synack_window(req))) { + /* Out of window: send ACK and drop. */ + if (!(flg & TCP_FLAG_RST) && + !tcp_oow_rate_limited(sock_net(sk), skb, +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1268,15 +1268,10 @@ static void tcp_v6_reqsk_send_ack(const + /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV + * sk->sk_state == TCP_SYN_RECV -> for Fast Open. + */ +- /* RFC 7323 2.3 +- * The window field (SEG.WND) of every outgoing segment, with the +- * exception of segments, MUST be right-shifted by +- * Rcv.Wind.Shift bits: +- */ + tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? + tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, + tcp_rsk(req)->rcv_nxt, +- req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, ++ tcp_synack_window(req) >> inet_rsk(req)->rcv_wscale, + tcp_rsk_tsval(tcp_rsk(req)), + READ_ONCE(req->ts_recent), sk->sk_bound_dev_if, + &key, ipv6_get_dsfield(ipv6_hdr(skb)), 0, -- 2.47.3