-
Notifications
You must be signed in to change notification settings - Fork 32
Description
Background
After introducing the PMP strategy, I continued working on hardening the system call to ensure U-mode tasks cannot trick the kernel into accessing arbitrary memory. However, I found that the current memory layout is not suitable for the syscall hardening.
Deadlock
Linmo currently links everything (Kernel, libc, M-mode apps, U-mode apps) into a single contiguous .text section.
To allow a U-mode task to run, we must map this shared .text into its memspace. This effectively makes any address in .text (including kernel functions) a "legal" address for syscalls.
This creates a logic loop for Pointer Validation:
- We want to ban users from passing kernel addresses to syscalls.
- But the user must have access to the
.textsection to run. - Therefore, the kernel address space becomes part of the user's legal memory space, bypassing the validation check.
This leads to a clear conclusion: KTEXT and UTEXT must be separated.
Proposed Strategy
After analyzing the trade-offs, I propose implementing a Section-Based Grouping (Hybrid) strategy.
Instead of a strict physical split, I plan to modify the linker script to group user-safe code into a dedicated region:
Define Sections:
.ktext: Pure kernel code + M-mode apps (Protected, M-mode only)..utext: U-mode apps (Executable by U-mode)..stext: Shared utilities (libc,vsnprintf) and compiler runtime support (e.g., integer division helpers).
PMP Enforcement:
- Use PMP to grant U-mode
X(Execute) orRXpermission to.utextand.stext. .ktextremains strictly locked.
This strikes a balance, solving the Pointer Validation deadlock with minimal changes to the build system and without requiring a complex shared library mechanism.
Discussion
I'm opening this issue to seek opinions on whether this strategy aligns with linmo's design philosophy, or if there is a better approach.