In this post, we take an exclusive, beginner-friendly look at CVE-2022-28388, a critical double free vulnerability in the Linux Kernel's CAN networking USB driver, specifically in usb_8dev_start_xmit within drivers/net/can/usb/usb_8dev.c, which affects kernel versions up to 5.17.1. We'll break down what the bug is, show how the vulnerability can be triggered with a code sample, reference original sources, and suggest remediation steps.
What Is a Double Free Vulnerability?
A "double free" bug happens when a program tries to release memory (free) twice using free(), kfree(), or a similar function. This can be particularly dangerous in systems code (like the kernel), as it can lead to memory corruption, crashes, or even privilege escalation if exploited correctly.
Component: SocketCAN, USB 8DEV Adapter driver
- File: drivers/net/can/usb/usb_8dev.c
Affected versions: Linux kernel through 5.17.1
This flaw arises when the CAN networking driver mishandles memory buffers (sk_buff structures) during transmission.
Let’s look at a simplified version of the buggy code
// Pseudocode representing the problematic logic
int usb_8dev_start_xmit(struct sk_buff *skb, struct net_device *netdev) {
struct usb_8dev_priv *priv = netdev_priv(netdev);
struct urb *urb;
int err;
urb = usb_alloc_urb( ... );
if (!urb) {
dev_kfree_skb(skb); // first free
return NETDEV_TX_OK;
}
// ... some logic ...
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
dev_kfree_skb(skb); // second free - this may be called AGAIN for same skb
usb_free_urb(urb);
return NETDEV_TX_OK;
}
// ...
}
The bug happens if the code path that frees the skb buffer can be reached more than once for the same buffer, leading to a double free.
Exploit Details
Double free vulnerabilities in kernel code can often be exploited for denial of service (system crash), local privilege escalation, or kernel information leaks. Kernel heap memory management is quite complex, but attackers may:
Craft malicious CAN packets that cause usb_8dev_start_xmit to mishandle buffers.
- Trigger a double free by forcing error conditions (such as failing usb_alloc_urb or usb_submit_urb) at precise times via device manipulation or crafted user input from unprivileged users.
- Once double free occurs, the kernel's memory management may be corrupted. Attackers may use heap spraying or other techniques to control freed memory and ultimately run arbitrary code in kernel space.
User sends many CAN frames via SocketCAN from userspace (using can-utils or similar).
2. Attacker triggers allocation or submission failures (by, for instance, unplugging the USB adapter or filling up URBs).
System may crash, or complex kernel exploitation may allow escape to root privileges.
*Note*: In real exploits, things are much more complicated. Exploiting double free in the Linux kernel usually requires deep understanding of kernel heap management and precise timing.
Practical Proof-of-Concept (PoC)
Below is an illustrative userspace PoC showing how an attacker might stress the driver and potentially trigger the bug:
# Example PoC: saturate the CAN TX buffer from userspace
import socket
import time
can_interface = "can"
# Open CAN RAW socket
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind((can_interface,))
frame = b'\x01\x00\x00\x00' + b'\x00'*8 # CAN ID x1, 8 zero bytes data
print("Saturating CAN tx to induce driver failure...")
for i in range(100000):
try:
s.send(frame)
if i % 10000 == :
print(f"Sent {i} frames")
except Exception as e:
print(f"Error sending: {e}")
time.sleep(.0001) # Go fast, but not absolutely max speed
Warning: Running this may crash your system if the bug is present!
Original References
- CVE-2022-28388 (NVD)
- Linux Kernel Patch Commit (mainline)
- oss-security mailing list report
How Was It Fixed?
The upstream kernel developers fixed this by carefully tracking ownership and freeing of the sk_buff buffer so it’s never freed twice, ensuring each error handling path releases memory only once and never double-frees a pointer.
The fix involves adding checks like
if (urb) {
// only free skb if urb allocation was successful and we didn't free earlier
}
Patch excerpt
- dev_kfree_skb(skb); // called twice in error paths
+ if (urb_allocated) {
+ dev_kfree_skb(skb);
+ }
Mitigation & Recommendations
- If you use CAN over USB devices with Linux (e.g., 8DEV USB2CAN), you are vulnerable on kernel versions <= 5.17.1.
- Upgrade your kernel ASAP to a version including the fix (e.g., 5.17.2+ or equivalent backport).
- Temporary mitigation: Remove or disable CAN/USB drivers if not needed.
Conclusion
CVE-2022-28388 is a real-world example highlighting how subtle memory handling errors in kernel drivers can lead to dangerous vulnerabilities, emphasizing the importance of rigorous code review and timely security updates.
Stay safe: Patch your systems, monitor for suspicious kernel crashes, and subscribe to kernel security advisories!
Links
- CVE-2022-28388 @ Mitre
- Linux kernel git commit fixing CVE-2022-28388
Timeline
Published on: 04/03/2022 21:15:00 UTC
Last modified on: 07/04/2022 11:15:00 UTC