Skip to content

x86: userspace store to address 0 does not fault - null page appears accessible in user address spaces #563

Description

@ryanbreen

Summary

A userspace volatile store to address 0 on x86_64 neither faults nor kills the process — the program keeps running and exits 0.

Evidence

While building the expected-red proof for #545 PR-A, userspace/programs/src/brk_test.rs was injected with a null store as its first statement:

fn main() {
    println!("=== brk Test Program ===");
    unsafe { write_volatile(0usize as *mut u64, 0xdead_beef); }

The ELF was rebuilt, the test disk repacked, and the kernel confirmed it loaded the injected binary (Loaded 'brk_test' from test disk (182496 bytes), matching the rebuilt ELF). The run then produced:

=== brk Test Program ===
USERSPACE BRK: ALL TESTS PASSED
[DEBUG] kernel::task::process_task: Process 4 'brk_test' (thread 14) exited with code 0

No page-fault line anywhere in the kernel log for that PID. The same harness with the store aimed at a kernel-half address instead (0xffff_ffff_8000_0000) faults correctly and kills the process:

[ERROR] kernel::interrupts: ✓ PAGE FAULT from USERSPACE (Ring 3 privilege test detected)
[ERROR] kernel::interrupts: Killing process brk_test (PID 4) due to page fault (CR3=0x4b11000)
TEST_TALLY: exited=10 nonzero=1 failed=[brk_test:-11]

So the fault path itself is healthy; specifically the null page does not trap.

Why it matters

Linux leaves the first page unmapped and enforces mmap_min_addr precisely so that a null dereference is a loud SIGSEGV rather than a silent memory write. If address 0 is mapped (or otherwise writable) in a Breenix user address space, every null-pointer bug in userspace becomes a silent corruption instead of a crash, and no test can assert the POSIX behaviour.

Open question for whoever picks this up

Two explanations fit the evidence and they have not been separated yet:

  1. Page 0 is actually mapped writable in the user address space (check the process page tables for the first page).
  2. LLVM elided or transformed the store (check the injected ELF's disassembly around main).

Worth resolving both ways: 1 is a kernel defect, 2 only means the probe was wrong and the question stays open.

Found during #545 PR-A round-2 verification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions