CVE-2026-98643 in Linux
Summary
by MITRE • 10/18/2026
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix out-of-bounds read of rtt_min in sock_ops
A sockops prog reading skops->rtt_min never checks the sk type: on the tcp_conn_request() path sock_ops->sk is a request_sock (non-full), and the ctx rewrite casts it to a tcp_sock (full) and reads rtt_min past the end of the request_sock, returning dirty adjacent memory.
SEC("sockops") int prog(struct bpf_sock_ops *skops) {
switch (skops->op) {
case BPF_SOCK_OPS_RWND_INIT: leak = skops->rtt_min; /* reads the request_sock OOB */ ... } }
For instance one such read returned rtt_min=0xffff8881, the high half of a leaked kernel pointer.
Guarding that cast is exactly what SOCK_OPS_GET_FIELD() does -- it checks is_locked_tcp_sock and returns 0 when sock_ops->sk is not a locked full socket. Every other tcp_sock field in sock_ops goes through it; rtt_min is the only one open-coded, so it skips the check.
Read rtt_min through SOCK_OPS_GET_FIELD() too. rtt_min is a bit special: it is a struct minmax and we only want the current min, so pass rtt_min.s[0].v. That is equivalent to the old hand-computed offset
offsetof(struct tcp_sock, rtt_min) + sizeof_field(struct minmax_sample, t)
(s[0] sits at rtt_min + 0 and .v at + sizeof(.t), i.e. what minmax_get()
returns), so the loaded field is unchanged and only the full-sock guard is added. The two BUILD_BUG_ON()s that protected the hand-computed offset are no longer needed.
Before patch:
0: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk 1: r1 = *(u32 *)(r1 +2324) ; ((tcp_sock *)sk)->rtt_min.s[0].v
After patch:
0: *(u64 *)(r1 +56) = r9 1: r9 = *(u8 *)(r1 +50) ; is_locked_tcp_sock 2: if r9 == 0 goto pc+4 ; not a locked full sock -> 0 3: r9 = *(u64 *)(r1 +56) 4: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk 5: r1 = *(u32 *)(r1 +2324) ; rtt_min.s[0].v
6: goto pc+2 7: r9 = *(u64 *)(r1 +56) 8: r1 = 0
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 10/18/2026
The Linux kernel contains a critical out-of-bounds read vulnerability within the BPF sockops subsystem, specifically affecting how the runtime accesses the round-trip time minimum value. This flaw arises from an improper type casting operation that fails to validate the underlying socket structure before accessing memory fields associated with TCP sockets. When a BPF program written for sock operations attempts to retrieve the rtt_min field via skops->rtt_min, it assumes the provided socket pointer refers to a fully established tcp_sock structure. However, during specific connection establishment phases such as tcp_conn_request(), the socket object referenced by sock_ops is actually a request_sock representing an incomplete or half-open connection state. Because request_sock and tcp_sock have different memory layouts and sizes, casting a request_sock pointer directly to a tcp_sock type results in accessing memory offsets that lie beyond the boundaries of the actual allocated structure for the request_sock.
This architectural mismatch leads to an out-of-bounds read where the kernel retrieves data from adjacent memory regions rather than valid socket fields. The immediate operational impact is the potential leakage of sensitive kernel information into user-space or BPF program contexts. In documented instances, this erroneous access has returned values such as 0xffff8881, which corresponds to the high half of a leaked kernel pointer address. Such leaks can aid attackers in bypassing memory protection mechanisms like Kernel Address Space Layout Randomization by revealing exact locations of critical data structures and code segments within the kernel space. This represents a significant security risk as it compromises the integrity of information isolation between the kernel and user-space applications utilizing eBPF programs for network monitoring or optimization tasks.
The root cause is identified as an inconsistency in how socket fields are accessed through helper macros versus direct field access. The sockops infrastructure provides a macro named SOCK_OPS_GET_FIELD which correctly validates whether the underlying socket is a locked, full TCP socket before allowing access to its members. All other tcp_sock fields utilized by sock_ops programs pass through this protective guard mechanism. However, rtt_min was historically implemented using hand-computed offset calculations that bypassed this essential type-checking logic. The fix involves refactoring the code to route the retrieval of rtt_min through the same SOCK_OPS_GET_FIELD macro used for other socket fields. This ensures that if the socket is not a fully established tcp_sock, the operation safely returns zero instead of attempting an invalid memory read.
From a classification perspective, this vulnerability aligns with CWE-125 Out-of-bounds Read and CWE-476 NULL Pointer Dereference in contexts where improper type assumptions lead to undefined behavior or information disclosure. In terms of attack vectors, it relates to ATT&CK technique T1083 File and Directory Discovery if the leak is used for reconnaissance, but more critically falls under Information Leak (T1504) due to the exposure of kernel pointers. The remediation strategy involves updating the BPF sockops implementation to enforce strict type checking before memory access. Developers must ensure that all socket field accesses utilize the standardized helper macros rather than manual offset arithmetic, thereby maintaining consistency and preventing similar boundary violations in future code modifications. This patch effectively closes the gap by adding a conditional check for is_locked_tcp_sock, ensuring that only valid full sockets are accessed while safely defaulting to zero for invalid types like request_socks.