-
Notifications
You must be signed in to change notification settings - Fork 24
Open
Description
Describe the bug
The kernel panics with called Option::unwrap() on a None value. This occurs when running a user-space program that performs aggressive memory allocation (allocating 1GB chunks), pushing the system into a low-memory state.
let offset = offset_get.unwrap();
| let offset = offset_get.unwrap(); |
To Reproduce
- Compile the program and run.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
/*
* PoC for potential arithmetic overflow in RuxOS get_meminfo()
*
* The crash occurs in ruxfs/src/arch/mod.rs:37 when calculating:
* freeram = (allocator.available_bytes() + allocator.available_pages() * memory_addr::PAGE_SIZE_4K)
*
* This can overflow if:
* 1. available_pages() is very large
* 2. The multiplication available_pages * 4096 overflows 64-bit integer
* 3. Adding available_bytes() to the result causes overflow
*
* User-space reachability analysis:
* - get_meminfo() is likely exposed through /proc/meminfo or similar interface
* - Reading /proc/meminfo triggers the vulnerable calculation
* - We can influence memory state by allocating/freeing large amounts of memory
*
* This PoC attempts to trigger the overflow by:
* 1. Allocating memory to manipulate available_pages count
* 2. Reading /proc/meminfo to trigger the vulnerable calculation
* 3. Repeating with different allocation patterns
*/
int main() {
FILE *fp;
char buffer[1024];
size_t alloc_size = 1024 * 1024 * 1024; // 1GB chunks
void *ptrs[100];
int i, iterations = 0;
printf("PoC: Attempting to trigger arithmetic overflow in get_meminfo()\n");
printf("Strategy: Allocate large memory chunks and read /proc/meminfo\n\n");
// Try different allocation patterns to manipulate memory state
while (iterations < 10) {
printf("Iteration %d: Allocating memory...\n", iterations + 1);
// Allocate memory chunks to influence available_pages
for (i = 0; i < 50; i++) {
ptrs[i] = malloc(alloc_size);
if (!ptrs[i]) {
printf("malloc failed at chunk %d\n", i);
break;
}
memset(ptrs[i], 0x41, alloc_size); // Touch the pages
}
printf("Allocated %d chunks of %zu bytes\n", i, alloc_size);
// Read /proc/meminfo to trigger the vulnerable calculation
printf("Reading /proc/meminfo to trigger get_meminfo()...\n");
fp = fopen("/proc/meminfo", "r");
if (fp) {
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}
fclose(fp);
} else {
printf("Could not open /proc/meminfo\n");
// Try alternative paths
fp = fopen("/sys/fs/meminfo", "r");
if (fp) {
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}
fclose(fp);
}
}
// Free some memory to change state
for (i = 0; i < 25; i++) {
if (ptrs[i]) {
free(ptrs[i]);
ptrs[i] = NULL;
}
}
printf("Freed half the allocations, reading /proc/meminfo again...\n");
// Trigger again with different memory state
fp = fopen("/proc/meminfo", "r");
if (fp) {
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}
fclose(fp);
}
// Clean up remaining allocations
for (i = 25; i < 50; i++) {
if (ptrs[i]) {
free(ptrs[i]);
}
}
iterations++;
printf("\n");
}
// Try with mmap for larger allocations
printf("Attempting with mmap for larger allocations...\n");
for (i = 0; i < 10; i++) {
void *mmap_ptr = mmap(NULL, alloc_size * 10, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mmap_ptr != MAP_FAILED) {
memset(mmap_ptr, 0x42, alloc_size * 10);
printf("mmap allocated %zu bytes\n", alloc_size * 10);
// Trigger the vulnerable code
fp = fopen("/proc/meminfo", "r");
if (fp) {
while (fgets(buffer, sizeof(buffer), fp)) {
if (strncmp(buffer, "MemFree:", 8) == 0 ||
strncmp(buffer, "MemTotal:", 9) == 0) {
printf("%s", buffer);
}
}
fclose(fp);
}
munmap(mmap_ptr, alloc_size * 10);
}
}
printf("PoC completed. If the kernel is vulnerable, it should have panicked.\n");
printf("Note: This PoC attempts to trigger the overflow through memory allocation\n");
printf("and reading /proc/meminfo, but success depends on the specific RuxOS\n");
printf("configuration and memory management implementation.\n");
return 0;
}
2.features.txt
alloc
paging
net
multitask
irq
fs
Environment
Logs
SeaBIOS (version 1.16.3-debian-1.16.3-2)
iPXE (https://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+7EFCAA40+7EF0AA40 CA00
Booting from ROM..
Initialize IDT & GDT...
8888888b. .d88888b. .d8888b.
888 Y88b d88P" "Y88b d88P Y88b
888 888 888 888 Y88b.
888 d88P 888 888 888 888 888 888 "Y888b.
8888888P" 888 888 `Y8bd8P' 888 888 "Y88b.
888 T88b 888 888 X88K 888 888 "888
888 T88b Y88b 888 .d8""8b. Y88b. .d88P Y88b d88P
888 T88b "Y88888 888 888 "Y88888P" "Y8888P"
arch = x86_64
platform = x86_64-qemu-q35
target = x86_64-unknown-none
smp = 1
build_mode = debug
log_level = warn
[ 0.189379 0 axfs_ramfs::dir:68] AlreadyExists sys
PoC: Attempting to trigger arithmetic overflow in get_meminfo()
Strategy: Allocate large memory chunks and read /proc/meminfo
Iteration 1: Allocating memory...
[ 1.935369 0:1 ruxmm::paging:61] available page num is 1023
[ 1.935801 0:1 ruxruntime::lang_items:14] panicked at api/ruxos_posix_api/src/imp/mmap/utils.rs:358:49:
called `Option::unwrap()` on a `None` value
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels