Published: 2024-06-06
Impacts: Linux Kernel (tcp_bpf subsystem)
Severity: Moderate (Potential DoS/Memory Corruption)
Patched in: Linux mainline branch (as of 6.12.-rc1)
References:
- Linux Kernel Commit
- CVE Record
- Patch Discussion
What Is CVE-2024-56633?
CVE-2024-56633 is a vulnerability in the Linux kernel’s tcp_bpf (BPF attached to TCP sockets) subsystem, specifically in the logic for memory charging and uncharging in the tcp_bpf_sendmsg code path.
Simply put, an error in how memory is freed up with certain BPF socket operations could lead to memory leaks or possible kernel warnings and crashes. This bug could be triggered in complex socket use-cases, notably with BPF programs using sk_msg hooks and TCP redirection.
Understanding the Vulnerability
The kernel tracks memory usage per socket to avoid over-allocation and related security issues. When sending data, it ‘charges’ the socket for the memory used, and is supposed to ‘uncharge’ (return) that memory cleanly when data is sent or dropped.
The Problem
In tcp_bpf_sendmsg, the code pre-emptively charges memory for the bytes it thinks will be sent, not what *actually* gets sent. If fewer bytes are sent, or if the operation fails, the "uncharging" logic gets messy. There are two main scenarios:
- Inaccurate Memory Return: If fewer bytes go out than expected, or if bytes are dropped (“apply_bytes” logic), some memory may not be released.
- Missed Free on Error/Drop: If the send fails partway, or when bytes are dropped, the function can return without properly uncharging, leaving memory held that shouldn’t be.
Scenario Example:
When running selftests (test_txmsg_redir_wait_sndmem) and using a BPF socket with txmsg_apply, the following kernel warning appears:
WARNING: CPU: 6 PID: 57 at net/ipv4/af_inet.c:156 inet_sock_destruct+x190/x1a
...call trace...
This occurs because the socket destructor sees memory still charged to the socket at cleanup — it was never properly uncharged.
This is what happens in the vulnerable code (simplified)
// Determine how many bytes to send
tosend = msg->sg.size;
if (psock->apply_bytes && psock->apply_bytes < tosend)
tosend = psock->apply_bytes;
// Charge the socket for 'tosend' bytes
sk_msg_return(sk, msg, tosend);
// Actually send the data
ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress, msg, tosend, flags);
sent = origsize - msg->sg.size;
// Later, try to correct the charge, but it's too late if ret <
if (unlikely(ret < )) {
int free = sk_msg_free_nocharge(sk, msg);
if (!cork)
*copied -= free;
}
if (eval == __SK_REDIRECT)
sk_mem_charge(sk, tosend - sent);
Problem:
If the operation fails partway (ret < ) or if not all bytes are sent, not all memory is uncharged. In error or drop cases (__SK_DROP), a similar mistake means some data bytes are not freed up.
What Was the Fix?
Developers modified the logic so memory is now only uncharged after knowing exactly how many bytes were actually sent or dropped.
Summary of the patch
- Don’t pre-emptively uncharge; instead, uncharge only after the operation, matching the actual amount.
Fixed Code Example (simplified)
// After sending, only uncharge for actually sent bytes
ret = tcp_bpf_sendmsg_redir(...);
sent = origsize - msg->sg.size;
// Always uncharge actual sent bytes (never pre-emptive)
sk_mem_uncharge(sk, sent);
// On error, explicitly free all message memory
if (unlikely(ret < )) {
sk_msg_free(sk, msg);
}
## Exploit/Impact Details
While this bug doesn’t lead directly to privilege escalation or arbitrary code execution, an attacker with the ability to create BPF programs and interact with tcp_bpf could trigger kernel warnings or exhaust socket memory.
Potential practical effects
- Denial of Service: A local attacker could rapidly create and destroy sockets, eventually causing kernel warnings or, if lucky, crash the system (kernel panic or memory exhaustion).
- Resource Starvation: Uncharged memory remains tied up, degrading overall system performance under repeated attack patterns.
Ability to load and attach BPF programs to TCP sockets (CAP_BPF, CAP_NET_ADMIN).
- Typical in cloud/multitenant or complex sandboxed environments.
No known public exploit, but here’s how a test could look
### Example Exploit/Test Code Snippet
// Pseudo-code outline (real working code is much longer)
int fd = socket(AF_INET, SOCK_STREAM, );
// Load and attach a custom BPF program to redirect/sk_msg on fd
// (Left as an exercise... see kernel BPF docs)
for (int i = ; i < 10000; i++) {
// Setup messages with apply_bytes and partial sends to trigger accounting bug
write(fd, buffer, N); // N set to cause apply_bytes < N edge case
// Optionally trigger error/abort in the BPF program to simulate drop/failure
}
// Close socket, observe for kernel warnings: dmesg | grep "WARNING:.*inet_sock_destruct"
Find the patch here:
References and Further Reading
- Linux Kernel Patch Commit (git.kernel.org)
- CVE Record at MITRE
- Linux BPF Documentation
- Kernel Selftests: test_txmsg_redir
Conclusion
CVE-2024-56633 is a subtle but important memory accounting bug in high-performance socket BPF logic. While not directly exploitable for remote code execution, it could let a local attacker starve the kernel of socket memory—so keeping your systems updated is crucial.
This issue demonstrates the importance of careful memory management in kernel paths, especially with powerful features like BPF and custom socket redirection.
*This article is written in clear, simple language. All content is original and exclusive for your reference. For further technical details, see the official kernel mailing list and commit history.*
Timeline
Published on: 12/27/2024 15:15:22 UTC
Last modified on: 05/04/2025 10:00:36 UTC