The Linux kernel, used in hundreds of millions of devices, is under constant scrutiny for bugs and vulnerabilities. In late 2023, a vulnerability tracked as CVE-2023-52465 was discovered and resolved. It affects the power supply subsystem, particularly the code responsible for probing SMB2 chargers, which are commonly used in smartphones and IoT devices. This post offers a detailed, exclusive breakdown of what went wrong, the security implications, code walkthroughs, and how it was fixed.
Overview: What Is CVE-2023-52465?
At its core, CVE-2023-52465 is a null pointer dereference vulnerability. It happens when certain memory allocation functions in the smb2_probe function aren’t checked for failure. If memory allocation fails and the code still tries to use the returned null pointer, the kernel will crash, leading to a denial of service, or in unlucky circumstances, a vector for further exploitation.
Summary
- Component affected: drivers/power/supply/smb2.c
- Issue: Failing to check if devm_kasprintf() or devm_kzalloc() return NULL before accessing the result.
Here’s the snippet that was problematic
/* Vulnerable example from the kernel before the fix */
pdata->name = devm_kasprintf(dev, GFP_KERNEL, "%s", id->name);
pdata->cache = devm_kzalloc(dev, size, GFP_KERNEL);
//... later in the code
strcpy(buffer, pdata->name); // If pdata->name is NULL -> crash!
The issue: If devm_kasprintf() or devm_kzalloc() fail (which can happen if the system is out of memory), they return NULL. The code above didn’t check the return value, and later used pdata->name and pdata->cache without checking, which could crash the kernel.
How could this be attacked?
A local user (or a misbehaving driver) could trigger the smb2_probe (for instance, by repeatedly trying to initialize SMB2 chargers). If the system is low on memory (easy to simulate on a test system), the devm_kasprintf() or devm_kzalloc() call could fail and return NULL, but the driver would still try to use the result. This would lead to a kernel oops (crash), halting the device.
Proof-of-Concept (PoC) Demo
While this is not a remote code execution bug, here’s an example of how a local user could exploit this:
# Simulate low-memory conditions:
echo 1 > /proc/sys/vm/drop_caches
stress --vm 2 --vm-bytes 98% --timeout 10s &
# Trigger probe (requires hardware or simulation), or via a custom kernel module
If the race is won, and the smb2_probe is called while there's almost no allocatable memory, the kernel could dereference NULL, causing a crash.
Kernel maintainers fixed this by introducing proper NULL pointer checks after every allocation
pdata->name = devm_kasprintf(dev, GFP_KERNEL, "%s", id->name);
if (!pdata->name)
return -ENOMEM; // Exit with error if allocation fails
pdata->cache = devm_kzalloc(dev, size, GFP_KERNEL);
if (!pdata->cache)
return -ENOMEM;
By checking if either allocation returns NULL, the function now gracefully handles out-of-memory conditions, and the crash is avoided.
Official Commit Fix:
power: supply: Fix null pointer dereference in smb2_probe
CVE Details:
Patch Discussion:
Lessons: Safer Allocations in Linux Kernel
Rule of thumb:
Always check the return value of any function that can allocate memory in the kernel.
- devm_kzalloc, devm_kasprintf, kmalloc, etc, can all return NULL if the allocation cannot be fulfilled.
Example of safe practice
ptr = kmalloc(size, GFP_KERNEL);
if (!ptr) {
printk(KERN_ERR "Memory allocation failed\n");
return -ENOMEM;
}
Why This Matters
A kernel oops, as caused by this bug, can take down an entire device. On servers and embedded devices, this can mean service outages, data loss, or bricked hardware. It also opens the door—albeit a narrow one—for more subtle attacks if more bugs are chained together.
You run a Linux kernel version before the patch (patch released in late 2023).
- Your hardware or userspace can trigger the smb2_probe (common on embedded/mobile).
You are safe if
- You have applied the patch, or are running a distribution kernel released after November 2023 that includes the fix.
Conclusion
CVE-2023-52465 is a good example of how even small mistakes—like failing to check for NULL—can lead to system-wide vulnerabilities. The fix is simple, but crucial. Remember, always check all kernel allocations.
For the curious, dig into the official patch or try exploring similar code paths in your drivers. And always write defensive code, even in C!
Timeline
Published on: 02/26/2024 16:27:48 UTC
Last modified on: 04/17/2024 19:16:10 UTC