Linux Kernel UDP Socket UAF (CVE-2026-98276): How sock_gettstamp() and bind() Race to Drop SOCK_RCU_FREE and How to Patch
Understand how CVE-2026-98276 races sock_gettstamp() against bind() to overwrite SOCK_RCU_FREE on Linux UDP sockets, why sysctl and firewalls cannot mitigate it, and how to verify kernel and livepatch fixes.
A conceptual illustration showing the socket lock serializing bind() (SOCK_RCU_FREE) and sock_gettstamp() (SOCK_TIMESTAMP) updates on the shared sk_flags word so the RCU grace period is preserved on socket teardown. This is not an actual debugger screenshot.
On November 7, 2026, security teams disclosed active in-the-wild exploitation of CVE-2026-98276 (CVSS 3.1 7.8 High per the Linux Kernel CNA; 7.0 per Red Hat)—a race condition in the Linux kernel's UDP socket implementation that lets an unprivileged local user trigger a deterministic kernel Use-After-Free (crashing the host or escalating privileges to root). Although upstream Linux fixed the flaw in commit 9ed55f3dbef4 ("net: lock the socket in sock_gettstamp()"), an attacker exploited the race on November 4 to crash a production CloudLinux 8 server 12 consecutive times before enterprise distribution patches had rolled out. CVE-2026-98276 Record, CloudLinux Advisory, TuxCare Incident Analysis, AlmaLinux Testing Announcement
The core operational takeaway: there is no sysctl toggle, boot parameter, firewall rule, or filesystem sandbox (such as CageFS) that mitigates CVE-2026-98276. Because any local process or compromised web/container account can trigger the race through its own UDP socket system calls (bind() racing against SIOCGSTAMP / SIOCGSTAMPNS_NEW), you must apply a patched kernel or rebootless livepatch—and verify livepatch status using kcarectl --patch-info | grep CVE-2026-98276 rather than kcarectl --info.
This guide examines the non-atomic bitfield race on sk->sk_flags, the distribution patch matrix, and crash-log forensics based on the NVD CVE-2026-98276 detail, SentinelOne's technical breakdown, and advisories from CloudLinux and TuxCare. It does not execute kernel exploit binaries; the local Python checks below model the read-modify-write lost update on sk_flags and verify livepatch inspection commands.
1. How Racing sock_gettstamp() Against bind() Drops SOCK_RCU_FREE
In the Linux kernel, a socket's behavioral flags share a single memory word (sk->sk_flags) modified via sock_set_flag() and sock_reset_flag(). Because those helpers use non-atomic bit operations (__set_bit() and __clear_bit()), kernel invariants require every caller mutating sk->sk_flags to hold the socket lock.
sock_gettstamp()—the handler behind SIOCGSTAMP and SIOCGSTAMPNS_NEW ioctl requests—violated this rule when enabling timestamping on a socket for the first time:
| Timeline Step | CPU 0: bind() → udp_lib_get_port() | CPU 1: ioctl(SIOCGSTAMPNS_NEW) → sock_gettstamp() | Kernel State & Resulting Use-After-Free |
| Step 1: Concurrent Read | Reads initial sk_flags word F into a register | Reads the same initial sk_flags word F without acquiring the socket lock | Both CPUs start from F (where neither SOCK_RCU_FREE nor SOCK_TIMESTAMP is set) |
| Step 2: Independent Bitwise OR | Computes F | BIT(SOCK_RCU_FREE), stores it to sk_flags, and publishes the socket to the UDP hash table via sk_add_node_rcu() | Inside sock_enable_timestamp(), computes F | BIT(SOCK_TIMESTAMP) | The UDP socket is now visible to lockless RCU readers in the UDP receive path |
| Step 3: Lost Update | bind() completes | Writes its stale word F | BIT(SOCK_TIMESTAMP) back to sk_flags | SOCK_RCU_FREE is overwritten and lost! The socket remains published in the RCU hash table without its RCU teardown flag |
| Step 4: Immediate Free on Close | User space closes the socket; sk_destruct() inspects SOCK_RCU_FREE | Seeing SOCK_RCU_FREE cleared, sk_destruct() frees the socket immediately instead of waiting for an RCU grace period | An in-flight UDP packet in udp_queue_rcv_one_skb → ipv4_pktinfo_prepare dereferences the freed struct sock, causing a slab-use-after-free |
How commit 9ed55f3dbef4 fixes the bug: Authored by Eric Dumazet (following a report by Jungwoo Lee and Wongi Lee), the upstream fix acquires the socket lock inside sock_gettstamp() only when SOCK_TIMESTAMP is not yet set—serializing the flag mutation against bind() while keeping subsequent timestamp reads lockless.
2. Why Firewalls, sysctl, and Filesystem Jails Do Not Block the Attack
Two operational boundaries make CVE-2026-98276 particularly dangerous on shared hosting servers, CI runners, and multi-tenant Kubernetes nodes:
- Purely local syscall vector: An attacker does not send crafted packets across the network perimeter. Any local user—or an attacker who compromises a single web application or container with shell/code execution—opens a UDP socket locally and races
bind()andioctl(SIOCGSTAMPNS_NEW)across two threads. Perimeter firewalls, WAFs, and filesystem isolation layers such asCageFSnever intercept these calls, and nosysctlor kernel boot flag disablessock_gettstamp().
- Proven production DoS and reproduced root escalation: On November 4, 2026, an attacker triggered 12 full reboots on a production CloudLinux 8 host configured with
kernel.panic_on_oops = 1. While the in-the-wild incident only crashed the server, CloudLinux engineers confirmed that they reproduced both the kernel crash and full local privilege escalation torootin-house.
3. Distribution Patch Matrix, Livepatch Verification, and Crash Forensics
As of November 8, 2026, patch availability varies significantly across enterprise Linux streams:
| Distribution / Kernel Stream | Affected? | Fixed Kernel / Rebootless Livepatch Status (as of Nov 8, 2026) | Recommended Action |
| Debian 12 (bookworm) & Debian 13 (trixie) | Yes | Debian 13 fixed in DSA-6568-1 (Oct 16); Debian 12 fixed in DLA-4841-1 (Oct 17); KernelCare livepatches available | Upgrade via apt update && apt upgrade and reboot, or apply KernelCare update |
| AlmaLinux 8 / 9 / 10 & CloudLinux 9 / 10 | Yes | Fixed kernels published in AlmaLinux testing repository: EL9: kernel-5.14.0-687.66.2.el9_8EL10: kernel-6.12.0-211.74.2.el10_2 | Enable almalinux-release-testing, run dnf update 'kernel*', and reboot if immediate patching is required |
| CloudLinux 7h & CloudLinux 8 (Kernel 4.18) | Yes | Fixed kernel 4.18.0-553.184.1.lve.1 in staged rollout;KernelCare livepatch live on the main feed for CloudLinux 8 | Run kcarectl --update for zero-downtime livepatching on CL8, or update kernel with --enablerepo=cloudlinux-rollout-10-bypass and reboot |
| CloudLinux 8 LTS & 9 LTS (TuxCare ELS) | Yes | Fixed in stable channel since Nov 2: kernel-lts-5.14.0-284.1101.el8.tuxcare.11.els17 (and .el9) or newer | Run yum update 'kernel*' and reboot; verify els17 or newer in uname -r |
| Red Hat Enterprise Linux (RHEL 7–10) | Yes | No official fixed RHEL kernel released as of Nov 7, 2026 (rated Moderate 7.0) | Restrict untrusted local code execution and monitor Red Hat errata or livepatch feeds |
Use the commands below to apply and verify a KernelCare livepatch (avoiding the --info trap) and to inspect previous boot logs for the exact crash signature:
4. Modeling the Non-Atomic sk_flags Lost Update and Lock Fix in Python
The dependency-free Python script below models why a non-atomic read-modify-write on sk->sk_flags loses SOCK_RCU_FREE when racing against sock_gettstamp(), how locking the first timestamp call preserves both bits, and why livepatch verification scripts must check --patch-info.
Scope Verified Locally
Running the script in a local Python environment verified three boundary cases:
- Unsynchronized race (
locked_first_call=False): SetsSOCK_TIMESTAMPwhile clobberingSOCK_RCU_FREE(rcu_free_preserved: False), resulting inuaf_on_close_during_udp_rx: True.
- Lock-serialized first call (
locked_first_call=True): Preserves bothSOCK_RCU_FREEandSOCK_TIMESTAMP, preventing the immediate free on close.
- Livepatch command check: Rejects
kcarectl --infoas insufficient (kcarectl_info_omits_cve_list) and confirms patching only whenCVE-2026-98276appears inkcarectl --patch-info.
5. Infrastructure Hardening Checklist
- Prioritize multi-tenant hosts and CI/CD build nodes: Any host where untrusted users, customers, or automated jobs can execute local binaries or scripts can reach
sock_gettstamp()and crash the kernel.
- Watch for follow-up patches on
sk_set_memalloc()andsk_clear_memalloc(): As noted in commit9ed55f3dbef4,sk_set_memalloc()andsk_clear_memalloc()also mutatesk_flagswithout holding the socket lock across callers such asnbd,iSCSI,NVMe over TCP,sunrpc, andWireGuard, and are slated for a separate upstream audit and fix.
- Enable persistent systemd journals (
Storage=persistent): On hosts withkernel.panic_on_oops = 1, persistent journaling ensures that crash traces inipv4_pktinfo_prepareorudp_destruct_commonsurvive an unexpected reboot for post-incident triage.
References
Last verified: November 9, 2026
Korean version:
Linux 커널 UDP 소켓 UAF 취약점(CVE-2026-98276) 해부: sock_gettstamp()와 bind() 경합이 SOCK_RCU_FREE를 지우는 원리와 패치 점검하기