Skip to content

fix(soundness): initialize user-provided buffers with random data before writing into them#2481

Queued
mkroening wants to merge 3 commits into
mainfrom
read-init
Queued

fix(soundness): initialize user-provided buffers with random data before writing into them#2481
mkroening wants to merge 3 commits into
mainfrom
read-init

Conversation

@mkroening

@mkroening mkroening commented Jun 16, 2026

Copy link
Copy Markdown
Member

#1606 changed our read methods to take &mut [MaybeUninit<u8>] instead of &mut [u8]. This was done to avoid UB when applications pass uninitialized buffers to read and similar functions, either through C or through Rust's unstable Read::read_buf.

445dac2 changed this back as part of #1891 to allow integration with the ecosystem's Read::read functions, that take a &mut [u8]. The soundness implications were not noticed.

This PR harmonizes Hermit's internal API by making recv also take a &mut [u8] instead of a &mut [MaybeUninit<u8>].

Then, it makes the APIs sound when uninitialized buffers are passed by introducing a fn init_buf(buf: &mut [MaybeUninit<u8>]) -> &mut [u8] that is currently an assembler story no-op. This function might need to do actual work if Hermit ever gains support for actual uninitialized memory that might return different values when read without being written to. This is not the case yet, so the no-op is fine.

For details, see rust-lang/unsafe-code-guidelines#527 (comment).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

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: aa76ee2 Previous: f83a235 Performance Ratio
startup_benchmark Build Time 76.90 s 77.08 s 1.00
startup_benchmark File Size 0.77 MB 0.73 MB 1.05
Startup Time - 1 core 0.73 s (±0.02 s) 0.73 s (±0.02 s) 1.01
Startup Time - 2 cores 0.75 s (±0.01 s) 0.75 s (±0.02 s) 1.00
Startup Time - 4 cores 0.74 s (±0.02 s) 0.76 s (±0.02 s) 0.98
multithreaded_benchmark Build Time 79.63 s 80.66 s 0.99
multithreaded_benchmark File Size 0.86 MB 0.86 MB 1.00
Multithreaded Pi Efficiency - 2 Threads 88.58 % (±6.20 %) 89.44 % (±5.91 %) 0.99
Multithreaded Pi Efficiency - 4 Threads 44.21 % (±2.80 %) 44.06 % (±2.65 %) 1.00
Multithreaded Pi Efficiency - 8 Threads 25.87 % (±1.27 %) 25.56 % (±1.89 %) 1.01
micro_benchmarks Build Time 75.06 s 87.20 s 0.86
micro_benchmarks File Size 0.86 MB 0.87 MB 1.00
Scheduling time - 1 thread 64.87 ticks (±2.38 ticks) 67.04 ticks (±1.91 ticks) 0.97
Scheduling time - 2 threads 38.48 ticks (±5.73 ticks) 39.33 ticks (±3.42 ticks) 0.98
Micro - Time for syscall (getpid) 3.17 ticks (±0.56 ticks) 3.43 ticks (±0.24 ticks) 0.93
Memcpy speed - (built_in) block size 4096 82047.71 MByte/s (±57055.07 MByte/s) 84527.91 MByte/s (±58322.62 MByte/s) 0.97
Memcpy speed - (built_in) block size 1048576 30873.18 MByte/s (±24800.98 MByte/s) 30845.87 MByte/s (±25037.16 MByte/s) 1.00
Memcpy speed - (built_in) block size 16777216 29277.27 MByte/s (±24001.55 MByte/s) 27492.52 MByte/s (±22708.20 MByte/s) 1.06
Memset speed - (built_in) block size 4096 82289.11 MByte/s (±57184.96 MByte/s) 84666.80 MByte/s (±58421.97 MByte/s) 0.97
Memset speed - (built_in) block size 1048576 31615.90 MByte/s (±25240.98 MByte/s) 31593.14 MByte/s (±25470.12 MByte/s) 1.00
Memset speed - (built_in) block size 16777216 30043.25 MByte/s (±24449.43 MByte/s) 28269.66 MByte/s (±23193.64 MByte/s) 1.06
Memcpy speed - (rust) block size 4096 75448.99 MByte/s (±52522.01 MByte/s) 74722.10 MByte/s (±52209.99 MByte/s) 1.01
Memcpy speed - (rust) block size 1048576 30780.15 MByte/s (±24797.51 MByte/s) 30824.11 MByte/s (±25054.28 MByte/s) 1.00
Memcpy speed - (rust) block size 16777216 29303.70 MByte/s (±24033.75 MByte/s) 27597.67 MByte/s (±22766.03 MByte/s) 1.06
Memset speed - (rust) block size 4096 76286.74 MByte/s (±53040.19 MByte/s) 74865.22 MByte/s (±52302.23 MByte/s) 1.02
Memset speed - (rust) block size 1048576 31531.23 MByte/s (±25235.38 MByte/s) 31565.59 MByte/s (±25484.76 MByte/s) 1.00
Memset speed - (rust) block size 16777216 30074.06 MByte/s (±24483.75 MByte/s) 28374.92 MByte/s (±23250.83 MByte/s) 1.06
alloc_benchmarks Build Time 73.06 s 81.01 s 0.90
alloc_benchmarks File Size 0.85 MB 0.81 MB 1.05
Allocations - Allocation success 91.32 % 91.32 % 1
Allocations - Deallocation success 100.00 % 100.00 % 1
Allocations - Pre-fail Allocations 61.46 % 61.46 % 1
Allocations - Average Allocation time 6161.95 Ticks (±120.12 Ticks) 6133.98 Ticks (±129.62 Ticks) 1.00
Allocations - Average Allocation time (no fail) 6781.88 Ticks (±142.07 Ticks) 6784.80 Ticks (±184.79 Ticks) 1.00
Allocations - Average Deallocation time 1280.12 Ticks (±288.24 Ticks) 1292.85 Ticks (±344.36 Ticks) 0.99
mutex_benchmark Build Time 72.81 s 81.90 s 0.89
mutex_benchmark File Size 0.87 MB 0.87 MB 1.00
Mutex Stress Test Average Time per Iteration - 1 Threads 12.06 ns (±0.31 ns) 12.08 ns (±0.27 ns) 1.00
Mutex Stress Test Average Time per Iteration - 2 Threads 38.90 ns (±2.10 ns) 17.94 ns (±3.62 ns) 2.17

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

@mkroening mkroening force-pushed the read-init branch 4 times, most recently from 5b6e6ba to 8286394 Compare June 16, 2026 15:00
@mkroening mkroening changed the title fix(soundness): freeze user-provided buffers before writing into them fix(soundness): initialize user-provided buffers with random data before writing into them Jun 16, 2026
Comment thread src/init_buf.rs Outdated
Comment thread src/init_buf.rs Outdated
@mkroening

Copy link
Copy Markdown
Member Author

@CAD97, thanks for your feedback!

I have tried to incorporate it: 8286394..6335688

@mkroening mkroening requested a review from CAD97 June 18, 2026 08:47
@mkroening

Copy link
Copy Markdown
Member Author

Rebased on main to resolve conflicts.

@mkroening mkroening added this pull request to the merge queue Jun 22, 2026
Any commits made after this event will not be merged.
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.

2 participants