Skip to content

feat: implement stack protection#2462

Open
zyuiop wants to merge 10 commits into
hermit-os:mainfrom
zyuiop:feat/stack-protection
Open

feat: implement stack protection#2462
zyuiop wants to merge 10 commits into
hermit-os:mainfrom
zyuiop:feat/stack-protection

Conversation

@zyuiop
Copy link
Copy Markdown
Contributor

@zyuiop zyuiop commented Jun 3, 2026

Isolate stacks in a separate virtual address space, just before the heap.
This ensures that stack overflows cause a page fault instead of silently corrupting the heap (for heap based stacks) or the page table (for the boot stack).

This has been tested only for x86_64 with UEFI, and will definitely not work on other platforms.

TODO:

  • Test/Fix on other platforms
  • Ensure we do this for all stacks (maybe it's not the case for IDT stacks after the first one)

@zyuiop zyuiop marked this pull request as draft June 3, 2026 11:04
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark Results

Details
Benchmark Current: 5cba8dc Previous: 28c7089 Performance Ratio
startup_benchmark Build Time 104.06 s 115.28 s 0.90
startup_benchmark File Size 0.74 MB 0.77 MB 0.96
Startup Time - 1 core 1.00 s (±0.05 s) 1.00 s (±0.03 s) 1.00
Startup Time - 2 cores 0.98 s (±0.04 s) 1.04 s (±0.05 s) 0.94
Startup Time - 4 cores 1.01 s (±0.06 s) 1.00 s (±0.06 s) 1.01
multithreaded_benchmark Build Time 104.00 s 118.33 s 0.88
multithreaded_benchmark File Size 0.84 MB 0.87 MB 0.96
Multithreaded Pi Efficiency - 2 Threads 91.03 % (±13.18 %) 92.34 % (±11.70 %) 0.99
Multithreaded Pi Efficiency - 4 Threads 45.74 % (±7.09 %) 45.83 % (±5.87 %) 1.00
Multithreaded Pi Efficiency - 8 Threads 24.38 % (±3.88 %) 25.71 % (±3.50 %) 0.95
micro_benchmarks Build Time 92.36 s 96.08 s 0.96
micro_benchmarks File Size 0.85 MB 0.88 MB 0.96
Scheduling time - 1 thread 73.06 ticks (±4.00 ticks) 73.85 ticks (±3.74 ticks) 0.99
Scheduling time - 2 threads 41.98 ticks (±5.48 ticks) 41.46 ticks (±4.37 ticks) 1.01
Micro - Time for syscall (getpid) 3.04 ticks (±0.20 ticks) 3.08 ticks (±0.19 ticks) 0.99
Memcpy speed - (built_in) block size 4096 76396.17 MByte/s (±52843.60 MByte/s) 73208.48 MByte/s (±50616.82 MByte/s) 1.04
Memcpy speed - (built_in) block size 1048576 29747.60 MByte/s (±24476.97 MByte/s) 29392.18 MByte/s (±24125.47 MByte/s) 1.01
Memcpy speed - (built_in) block size 16777216 26396.63 MByte/s (±21748.69 MByte/s) 23751.74 MByte/s (±19605.56 MByte/s) 1.11
Memset speed - (built_in) block size 4096 76679.82 MByte/s (±53055.45 MByte/s) 73313.38 MByte/s (±50689.78 MByte/s) 1.05
Memset speed - (built_in) block size 1048576 30486.18 MByte/s (±24889.00 MByte/s) 30169.43 MByte/s (±24587.38 MByte/s) 1.01
Memset speed - (built_in) block size 16777216 27141.33 MByte/s (±22209.47 MByte/s) 24402.29 MByte/s (±20008.02 MByte/s) 1.11
Memcpy speed - (rust) block size 4096 65888.22 MByte/s (±46131.28 MByte/s) 66427.37 MByte/s (±46490.49 MByte/s) 0.99
Memcpy speed - (rust) block size 1048576 29491.56 MByte/s (±24282.12 MByte/s) 29425.11 MByte/s (±24175.79 MByte/s) 1.00
Memcpy speed - (rust) block size 16777216 26677.40 MByte/s (±22039.06 MByte/s) 24403.77 MByte/s (±20179.96 MByte/s) 1.09
Memset speed - (rust) block size 4096 65954.70 MByte/s (±46178.34 MByte/s) 66262.32 MByte/s (±46403.75 MByte/s) 1.00
Memset speed - (rust) block size 1048576 30305.98 MByte/s (±24765.30 MByte/s) 30172.11 MByte/s (±24599.55 MByte/s) 1.00
Memset speed - (rust) block size 16777216 27141.73 MByte/s (±22247.73 MByte/s) 25069.95 MByte/s (±20590.63 MByte/s) 1.08
alloc_benchmarks Build Time 90.10 s 91.43 s 0.99
alloc_benchmarks File Size 0.81 MB 0.85 MB 0.96
Allocations - Allocation success 100.00 % 100.00 % 1
Allocations - Deallocation success 100.00 % 100.00 % 1
Allocations - Pre-fail Allocations 100.00 % 100.00 % 1
Allocations - Average Allocation time 4670.12 Ticks (±66.32 Ticks) 4633.96 Ticks (±62.19 Ticks) 1.01
Allocations - Average Allocation time (no fail) 4670.12 Ticks (±66.32 Ticks) 4633.96 Ticks (±62.19 Ticks) 1.01
Allocations - Average Deallocation time 905.07 Ticks (±94.64 Ticks) 683.28 Ticks (±99.25 Ticks) 1.32
mutex_benchmark Build Time 92.44 s 90.68 s 1.02
mutex_benchmark File Size 0.85 MB 0.88 MB 0.96
Mutex Stress Test Average Time per Iteration - 1 Threads 13.72 ns (±0.63 ns) 13.82 ns (±0.84 ns) 0.99
Mutex Stress Test Average Time per Iteration - 2 Threads 18.46 ns (±8.82 ns) 14.48 ns (±0.75 ns) 1.27

This comment was automatically generated by workflow using github-action-benchmark.

@zyuiop zyuiop force-pushed the feat/stack-protection branch 2 times, most recently from 8b21c11 to 2774988 Compare June 5, 2026 15:20
@zyuiop
Copy link
Copy Markdown
Contributor Author

zyuiop commented Jun 5, 2026

Okay I have spent some time trying to port to arm/riscV

@zyuiop zyuiop marked this pull request as ready for review June 5, 2026 15:21
@zyuiop zyuiop force-pushed the feat/stack-protection branch 4 times, most recently from c1c52b7 to 7b12cb1 Compare June 5, 2026 17:25
@zyuiop
Copy link
Copy Markdown
Contributor Author

zyuiop commented Jun 5, 2026

I extracted the first two commits to #2466 so they can be merged independently :)

@zyuiop zyuiop force-pushed the feat/stack-protection branch from 7b12cb1 to 2e55501 Compare June 5, 2026 18:22
@zyuiop zyuiop force-pushed the feat/stack-protection branch from 0a487f6 to cb2b4e8 Compare June 5, 2026 20:43
@zyuiop
Copy link
Copy Markdown
Contributor Author

zyuiop commented Jun 5, 2026

Note than on ARM/RISC, the boot stack is not moved as we do in x86_64, so it is not protected.

I have a branch for RISCV on my PC, I can push it if there is interest.

@zyuiop
Copy link
Copy Markdown
Contributor Author

zyuiop commented Jun 5, 2026

I can reproduce the Laplace iterations problem locally on main too, so I don't think this is my fault

@zyuiop zyuiop force-pushed the feat/stack-protection branch from c7bf3e9 to 5cba8dc Compare June 5, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant