tcp: rstreason: fully support in tcp_check_req()
authorJason Xing <kernelxing@tencent.com>
Fri, 10 May 2024 12:25:02 +0000 (20:25 +0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 14 May 2024 00:33:57 +0000 (17:33 -0700)
We're going to send an RST due to invalid syn packet which is already
checked whether 1) it is in sequence, 2) it is a retransmitted skb.

As RFC 793 says, if the state of socket is not CLOSED/LISTEN/SYN-SENT,
then we should send an RST when receiving bad syn packet:
"fourth, check the SYN bit,...If the SYN is in the window it is an
error, send a reset"

Signed-off-by: Jason Xing <kernelxing@tencent.com>
Link: https://lore.kernel.org/r/20240510122502.27850-6-kerneljasonxing@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/rstreason.h
net/ipv4/tcp_minisocks.c

index 7ae5bb5..2575c85 100644 (file)
@@ -16,6 +16,7 @@
        FN(TCP_OLD_ACK)                 \
        FN(TCP_ABORT_ON_DATA)           \
        FN(TCP_TIMEWAIT_SOCKET)         \
+       FN(INVALID_SYN)                 \
        FN(MPTCP_RST_EUNSPEC)           \
        FN(MPTCP_RST_EMPTCP)            \
        FN(MPTCP_RST_ERESOURCE)         \
@@ -76,6 +77,13 @@ enum sk_rst_reason {
        /* Here start with the independent reasons */
        /** @SK_RST_REASON_TCP_TIMEWAIT_SOCKET: happen on the timewait socket */
        SK_RST_REASON_TCP_TIMEWAIT_SOCKET,
+       /**
+        * @SK_RST_REASON_INVALID_SYN: receive bad syn packet
+        * RFC 793 says if the state is not CLOSED/LISTEN/SYN-SENT then
+        * "fourth, check the SYN bit,...If the SYN is in the window it is
+        * an error, send a reset"
+        */
+       SK_RST_REASON_INVALID_SYN,
 
        /* Copy from include/uapi/linux/mptcp.h.
         * These reset fields will not be changed since they adhere to
index 7d54356..b93619b 100644 (file)
@@ -879,7 +879,7 @@ embryonic_reset:
                 * avoid becoming vulnerable to outside attack aiming at
                 * resetting legit local connections.
                 */
-               req->rsk_ops->send_reset(sk, skb, SK_RST_REASON_NOT_SPECIFIED);
+               req->rsk_ops->send_reset(sk, skb, SK_RST_REASON_INVALID_SYN);
        } else if (fastopen) { /* received a valid RST pkt */
                reqsk_fastopen_remove(sk, req, true);
                tcp_reset(sk, skb);