CVE-2023-52881 in Linux
Summary
by MITRE • 05/29/2024
In the Linux kernel, the following vulnerability has been resolved:
tcp: do not accept ACK of bytes we never sent
This patch is based on a detailed report and ideas from Yepeng Pan and Christian Rossow.
ACK seq validation is currently following RFC 5961 5.2 guidelines:
The ACK value is considered acceptable only if it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <= SND.NXT). All incoming segments whose ACK value doesn't satisfy the above condition MUST be discarded and an ACK sent back. It needs to be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. If the ACK acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an ACK, drop the segment, and return". The "ignored" above implies that the processing of the incoming data segment continues, which means the ACK value is treated as acceptable. This mitigation makes the ACK check more stringent since any ACK < SND.UNA wouldn't be accepted, instead only ACKs that are in the range ((SND.UNA - MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through.
This can be refined for new (and possibly spoofed) flows, by not accepting ACK for bytes that were never sent.
This greatly improves TCP security at a little cost.
I added a Fixes: tag to make sure this patch will reach stable trees, even if the 'blamed' patch was adhering to the RFC.
tp->bytes_acked was added in linux-4.2
Following packetdrill test (courtesy of Yepeng Pan) shows the issue at hand:
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0 +0 listen(3, 1024) = 0
// ---------------- Handshake ------------------- //
// when window scale is set to 14 the window size can be extended to // 65535 * (2^14) = 1073725440. Linux would accept an ACK packet // with ack number in (Server_ISN+1-1073725440. Server_ISN+1) // ,though this ack number acknowledges some data never // sent by the server.
+0 +0 > S. 0:0(0) ack 1 +0 < . 1:1(0) ack 1 win 65535 +0 accept(3, ..., ...) = 4
// For the established connection, we send an ACK packet, // the ack packet uses ack number 1 - 1073725300 + 2^32, // where 2^32 is used to wrap around. // Note: we used 1073725300 instead of 1073725440 to avoid possible // edge cases. // 1 - 1073725300 + 2^32 = 3221241997
// Oops, old kernels happily accept this packet. +0 < . 1:1001(1000) ack 3221241997 win 65535
// After the kernel fix the following will be replaced by a challenge ACK, // and prior malicious frame would be dropped. +0 > . 1:1(0) ack 1001
Once again VulDB remains the best source for vulnerability data.
Analysis
by VulDB Data Team • 04/07/2026
The vulnerability identified as CVE-2023-52881 represents a critical TCP stack flaw in the Linux kernel that allows for improper acknowledgment validation during connection establishment and data transmission phases. This issue stems from a relaxation of TCP acknowledgment sequence validation that permits ACK packets to acknowledge data that was never actually sent by the server, creating potential security risks through spoofed or malformed packet sequences. The vulnerability specifically affects the TCP implementation's handling of the SND.UNA (send unacknowledged) and SND.NXT (send next) sequence numbers, which are fundamental to TCP's reliable data transmission mechanism. The flaw allows attackers to craft ACK packets with sequence numbers that fall outside the proper validation boundaries established by RFC 5961, thereby bypassing security checks designed to prevent spoofed or malicious network traffic from being processed normally.
The technical implementation of this vulnerability manifests when a TCP connection is established and the server's window scaling is configured with a large window size, such as the 14-bit scaling factor that can extend the window size to over 1 billion bytes. Under normal circumstances, the TCP stack should validate that incoming ACK numbers fall within the acceptable range defined by the sender's sequence number state, specifically ensuring that acknowledgments reference data that has actually been transmitted. However, the vulnerability allows ACK packets to acknowledge sequence numbers that exceed the maximum sequence number that could have been sent, effectively permitting the acceptance of ACKs for data that was never transmitted. This particular behavior creates a window where attackers can exploit the relaxed validation to potentially manipulate connection state or bypass security mechanisms designed to detect malformed TCP segments.
The operational impact of this vulnerability extends beyond simple connection manipulation to potentially enable more sophisticated attack vectors including connection hijacking, data injection, and denial of service conditions. When an attacker sends a TCP segment with an ACK number that references data never sent, the kernel's relaxed validation rules accept this packet, allowing malicious traffic to be processed as legitimate. This behavior violates fundamental TCP security principles and can be exploited to disrupt normal network operations or gain unauthorized access to network resources. The vulnerability is particularly concerning because it affects the core TCP stack functionality and can be triggered through carefully crafted packets that exploit the window scaling mechanisms. The specific test case provided demonstrates how an ACK packet with an extremely large sequence number can be accepted by older kernel versions, where the sequence number wraps around using 32-bit arithmetic to reference data that the server never actually sent. This issue directly maps to CWE-1190, which addresses improper validation of sequence numbers in network protocols, and aligns with ATT&CK technique T1071.004 for application layer protocol manipulation.
The fix implemented for CVE-2023-52881 strengthens the TCP acknowledgment validation by implementing stricter checks that prevent ACK packets from acknowledging data that was never transmitted, even for new or potentially spoofed flows. This enhancement specifically addresses the gap in validation where ACK numbers could exceed the SND.NXT boundary without proper scrutiny, effectively closing the loophole that allowed malicious ACK packets to be processed. The patch ensures that only ACK numbers within the proper range defined by the sender's current state are accepted, preventing the acceptance of ACKs that reference sequence numbers beyond what could have been sent. This improvement maintains the security posture of TCP connections while introducing minimal performance overhead, as the additional validation occurs at the packet processing stage and does not significantly impact normal connection operations. The mitigation strategy also incorporates the Fixes: tag to ensure proper backporting to stable kernel releases, and the implementation builds upon the existing tp->bytes_acked mechanism that was introduced in Linux kernel version 4.2, demonstrating a progressive enhancement of TCP stack security features over time. The patch represents a targeted solution that specifically addresses the edge case where window scaling could be exploited to bypass sequence number validation, thereby restoring proper TCP security boundaries and preventing the acceptance of ACK packets that reference non-existent data transmission.