summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp_minisocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r--net/ipv4/tcp_minisocks.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index ddc4b17a826b..6ab3e3a0b431 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -833,7 +833,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
* elsewhere and is checked directly against the child socket rather
* than req because user data may have been sent out.
*/
- if ((flg & TCP_FLAG_ACK) && !fastopen &&
+ if ((flg & TCP_FLAG_ACK) && !(flg & TCP_FLAG_RST) && !fastopen &&
(TCP_SKB_CB(skb)->ack_seq !=
tcp_rsk(req)->snt_isn + 1))
return sk;
@@ -872,6 +872,16 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
flg &= ~TCP_FLAG_SYN;
}
+ /* RFC 5961 section 3.2, as clarified by RFC 9293 section
+ * 3.10.7.4, requires a challenge ACK for a non-exact
+ * in-window RST in SYN-RECEIVED.
+ */
+ if ((flg & TCP_FLAG_RST) &&
+ TCP_SKB_CB(skb)->seq != tcp_rsk(req)->rcv_nxt) {
+ tcp_reqsk_send_challenge_ack(sk, skb, req);
+ return NULL;
+ }
+
/* RFC793: "second check the RST bit" and
* "fourth, check the SYN bit"
*/