A Linux kernel TCP flaw that sat unnoticed for about 11 years lets a remote attacker with no credentials crash a server by sending packets to any ordinary listening port, and as of Sunday, November 15, most major distributions have not yet shipped a fixed kernel.
The bug is tracked as CVE-2026-99288 and named NoisyTCP by its finder, security researcher Hyunwoo Kim (@v4bel). It is a race condition in the kernel code that matches incoming TCP packets to sockets.
The Linux kernel CVE team published the record on Tuesday, November 10, without a CVSS score, and NVD has not scored it either. The flaw was introduced in Linux 4.4 by a commit dated October 3, 2015.
Kim published a technical write–up on GitHub after the embargo on the linux-distros mailing list ended. He says the flaw affects “almost all Linux distributions” and that Nginx, Apache, and SSH in their default configurations are all reachable targets, because the only thing an attacker needs is the ability to send TCP packets to a listening port.
Upstream fixes are in Linux 6.12.117, 6.18.63 and 7.3.4. Oracle has shipped fixed Unbreakable Enterprise Kernel packages, Debian has the fix only in unstable, and Ubuntu lists no fixed package for any release.
How the NoisyTCP Race Works
When a TCP packet arrives, the kernel looks up the socket it belongs to in a table called ehash, the established-connections hash. That lookup takes no lock, so that many CPU cores can process packets at once. The sockets live in memory caches marked SLAB_TYPESAFE_BY_RCU, which means a freed socket’s memory can be handed straight to a new socket of the same type while another core is still looking at the old address.
The kernel guards against that reuse by taking a reference to the socket it found and then checking again that the addresses and ports, the “tuple”, still match. According to the CVE record, __inet_lookup_established() and __inet6_lookup_established() did not also check whether the object was still in the hash table.
NoisyTCP abuses that gap with a request socket, the small placeholder the kernel keeps for a half-open connection. One core finds an existing request socket. A second core frees it and, through the SYN cookie path, allocates a new request socket with the same tuple at the same memory address.
The first core takes its reference on the new object and the tuple check passes, but the new request socket was never hashed and has no listening socket attached. tcp_v4_rcv() then reads the connection state through that NULL listener pointer, and the kernel panics inside an interrupt handler.
The upstream fix, commit 4e2b3ef19e0e, is titled “inet: reject unhashed sockets during established lookups” and was written by Kim himself. After taking a reference, both the IPv4 and IPv6 lookups now check whether the socket is unhashed; if it is, or the tuple no longer matches, they drop the reference and restart the lookup. The patch also changes the SYN cookie, TCP Fast Open, and request-migration failure paths to release request sockets with reqsk_put() instead of freeing them directly.
What an Attacker Needs, and How Long It Takes
Kim lists two conditions. The target must process packets on more than one CPU, which means a network interface with two or more receive (RX) queues, or Receive Packet Steering (RPS) enabled. And the attacker must be able to reach a plain TCP listener. No login, no application bug, and no user action are involved.
To push related packets onto different cores, Kim’s proof of concept uses the fact that IPv4 fragments and regular TCP packets hash to different receive queues.
The timing depends heavily on the hardware. On QEMU/KVM virtual machines, Kim reports that default Nginx, Apache, and SSH servers crash in about 5 seconds to 2 minutes because virtual CPU preemption widens the race window. On a quiet bare-metal server with 8 RX queues, the same attack on Nginx took about 14 hours with a proof of concept tuned for that machine. Cloud instances and VPS hosts are virtual machines, so they sit on the fast side of that range.
Containers offer no isolation here. The crash is in the host kernel, so Kim notes that an attack on one containerised web server takes down the whole host and every other container on it.
Is NoisyTCP More Than a Denial-of-Service Attack?
Kim’s title calls NoisyTCP “pre-auth remote corruption“, and his write-up describes a second trigger path in which a full child socket, not a request socket, is recycled under a stale lookup. That path produces a remote use-after-free, a memory-corruption bug class that can sometimes be exploited to execute code. Kim says it needs nested races and is “generally hard” to trigger without special techniques.
Kim does not claim remote code execution for CVE-2026-99288, and neither does any vendor. The kernel CVE record documents only the NULL pointer crash, and Red Hat describes the flaw as a remote denial-of-service flaw. No CVSS score from the kernel CVE team or NVD existed when this article was published.
Which Distributions Have a CVE-2026-99288 Fix
| Distribution | Status as of November 15, 2026 | Fixed package or advisory |
|---|---|---|
| Upstream stable | Fixed | 6.12.117, 6.18.63, 7.3.4 |
| Oracle Linux 7 and 8 (UEK) | Fixed November 12 | ELSA-2026-500630 |
| Debian | Fixed in sid; bookworm, trixie and forky vulnerable | Security tracker |
| Ubuntu 14.04 to 26.10 | Listed as affected; no fixed package | CVE page |
| Red Hat Enterprise Linux | CVE page published November 11; no erratum found | CVE page |
| CIQ Rocky Linux from CIQ 8 and 10 | Backports proposed | PR 1795, PR 1791 |
The kernel CVE record lists fixes only for the 6.12, 6.18 and 7.3 stable branches. It lists no fixed release for the older long-term branches, 5.10, 5.15, 6.1 and 6.6, even though every kernel from 4.4 onward carries the bug. Oracle published two further UEK advisories for the flaw on November 12 and 13. Cyber Kendra found no advisory for CVE-2026-99288 from SUSE or Amazon Linux as of November 15.
Is CVE-2026-99288 Being Exploited?
No vendor has reported attacks using CVE-2026-99288, and no public exploit has been indexed for it. Kim’s GitHub repository describes the proof of concept he used for testing but does not include the code, nor does it say whether he will release it.
The CVE record itself confirms that a proof of concept exists, reproduces the crash, and includes the resulting kernel oops from a 7.3.0 test kernel.
What Linux Admins Should Do Now
Install a kernel that includes commit 4e2b3ef19e0e, then reboot into it. For self-built kernels, that means 6.12.117, 6.18.63, 7.3.4 or later. Run uname -r after the reboot to confirm the running version, because an installed but unbooted kernel changes nothing. Kim calls the patch the priority.
Where no fixed package exists yet, Kim lists two workarounds. The first is to turn off SYN cookies with sudo sysctl -w net.ipv4.tcp_syncookies=0. The setting is per network namespace, so it has to be applied inside every container that has its own namespace, and it removes the kernel’s built-in protection against SYN flood attacks. Check the current value with sysctl net.ipv4.tcp_syncookies.
The second workaround is to reduce the network interface to a single RX queue and disable RPS and Receive Flow Steering (RFS), which keeps packet processing on one core at the cost of network throughput. Kim’s write-up gives no commands for this step.
No distribution vendor had published its own mitigation guidance for CVE-2026-99288 that Cyber Kendra could find at the time of writing.
CVE-2026-99288 is the second remotely reachable TCP flaw dating to Linux 4.4 to surface in a month, after CVE-2026-98432, which the kernel CVE team scored 9.8 in October. Kim also found the Januscape KVM escape (CVE-2026-53359) disclosed in July and the six Infinity Core kernel bugs published on October 17.
Community Discussion
Join the conversation. Ask questions, share solutions, and help others.
Be the first to start the discussion!
