Skip to content

Implement mprotect()-based module isolation for the Linux/GNU simulation port (and Windows equivalent) #557

Description

@fdesbiens

Summary

The Linux/GNU simulation target has no module port. Adding one as a test scaffold only (no memory isolation) would allow the module manager sources to compile and be unit-tested on Linux but would not implement:

  • Memory isolation (no mprotect()/MPU enforcement)
  • The privileged dispatcher gate (no SVC-equivalent)
  • Module binary loading from filesystem images
  • Bounds checking on module-to-kernel pointer parameters

The goal of this issue is to go further and implement real mprotect()-based isolation in the Linux simulation port, making it useful for module boundary validation, developer tooling, and fuzzing.

Proposed implementation: mprotect()-based isolation

Use mprotect() as a software analog to the ARM MPU:

Embedded (ARM Cortex-M) Linux simulation
8–16 MPU region registers Two mprotect() region descriptors
SVC instruction → SVC handler C dispatcher gate with mprotect() permission swap
Hardware MPU reload on context switch mprotect() syscall (~1 µs per switch)
MEMFAULT exception SIGSEGVsigaction() handler

New directory structure

ports_module/linux/gnu/
├── inc/
│   └── txm_module_port.h                        # port header
└── module_manager/src/
    ├── txm_module_manager_mm_setup.c            # mmap regions, mprotect enforcement
    ├── txm_module_manager_user_mode_entry.c     # replaces SVC gate
    └── txm_module_manager_memory_fault.c        # SIGSEGV handler → module fault callback

TXM_MODULE_MANAGER_PORT_EXTENSION would add two mprotect region descriptors to TXM_MODULE_INSTANCE (code region + data region).

Dispatcher gate sketch

ALIGN_TYPE _txm_module_manager_user_mode_entry(ULONG request, ...)
{
    ALIGN_TYPE result;
    mprotect(module_code, code_size, PROT_NONE);
    mprotect(module_data, data_size, PROT_NONE);
    result = _txm_module_manager_kernel_dispatch(request, ...);
    mprotect(module_code, code_size, PROT_READ | PROT_EXEC);
    mprotect(module_data, data_size, PROT_READ | PROT_WRITE);
    return result;
}

Fault detection

static void module_fault_handler(int sig, siginfo_t *si, void *ctx)
{
    /* Walk module list, find owner of faulting address, invoke module fault callback */
    _txm_module_manager_fault_notify(faulting_module);
}

Known limitation: process-wide protection

mprotect() changes affect the entire process. In a multi-threaded scenario, only one module can be active at a time without a global lock. A future upgrade to Intel MPK (pkey_mprotect() + wrpkru) on capable hardware (Linux on Skylake+/Zen 2+) would remove this constraint because the PKRU register is thread-local.

Windows equivalent

A Windows counterpart in ports_module/win32/msvc/ is equally feasible using VirtualProtect() and AddVectoredExceptionHandler():

Linux Windows
mmap(MAP_ANONYMOUS|MAP_PRIVATE) VirtualAlloc(MEM_COMMIT|MEM_RESERVE)
mprotect(..., PROT_NONE) VirtualProtect(..., PAGE_NOACCESS, &old)
mprotect(..., PROT_READ|PROT_WRITE) VirtualProtect(..., PAGE_READWRITE, &old)
mprotect(..., PROT_READ|PROT_EXEC) VirtualProtect(..., PAGE_EXECUTE_READ, &old)
sigaction(SIGSEGV, ...) AddVectoredExceptionHandler(...)
SIGSEGV EXCEPTION_ACCESS_VIOLATION

Note: Intel MPK is not available on Windows. VirtualProtect() is the ceiling on that platform, which is acceptable for a simulation/test port.

Why this matters

  1. Module developer tooling: Catch isolation violations (stray pointer into kernel memory) as SIGSEGV instead of silent corruption on developer workstations, without requiring embedded hardware.
  2. Fuzzing infrastructure: AFL/libfuzzer can target module inputs with real boundary detection on Linux.
  3. CI coverage: Isolation-breach scenarios can be validated in automated pipelines without a hardware target.

Scope

This is a new platform feature. The ports_module/linux/gnu/ directory and CMake wiring need to be created from scratch as part of this work.

Estimated effort: ~500–800 lines of new C code plus tests for each platform port.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or enhancement request

    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