std::sys::pal::sgx: fix mismatched alloc/free alignment - #161895
Open
phlip9 wants to merge 1 commit into
Open
Conversation
Collaborator
|
Thanks for the pull request, and welcome! The Rust Project has assigned @JohnTitor (or someone else) to review your changes, you should hear from them (or someone else) within the next two weeks. Please see the contribution instructions and our LLM policy for more information. Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
`User::new_uninit_bytes` and `User::drop` are asking the host to alloc/dealloc memory with potentially mismatched alignment, as the enclave side is unconditionally over-aligning on allocation but not doing the same on free. - Ex: `User::<ByteBuffer>` -> `alloc(_, align=8)` -> `drop()` -> `free(_, align=1)` For most hosts running stock x86_64-linux + glibc malloc, I don't believe this mismatch is an issue, since posix `free` ignores the alignment anyway. My guess is that if you're using jemalloc, which does care about the dealloc alignment, then something _might_ go wrong. It's also not clear that we can just round-up the alignment on `free`, since `User::from_raw` exists, and there's various places that call it outside std. We should probably just remove the min. alignment until we come up with a more satisfactory solution. My guess is that the right place to do the min. alignment optimization is in the host-side enclave-runner: <https://github.com/fortanix/rust-sgx/blob/be93e7abe92eff4b5610e15fe21b16196ace1e6e/intel-sgx/enclave-runner-sgx/src/usercalls/mod.rs#L1596> and other places that hand memory to the SGX enclave. NB. The min. alignment exists for performance reasons (see: `copy_from_userspace`). It's highly preferable if all memory copied from userspace is at least 8 byte aligned, otherwise we have to fallback to a super slow copy routine for the unaligned prefix (and suffix).
phlip9
force-pushed
the
phlip9/fix-sgx-alloc-align
branch
from
August 27, 2026 23:06
f5080fe to
3e5c0fa
Compare
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why the PR?
I've got a local
miribranch that's able to testx86_64-fortanix-unknown-sgx, so I can get better assurance about our enclaves. It's now complaining about a bunch of stuff in std πContext
x86_64-fortanix-unknown-sgxenclaves can request the untrusted host enclave runner to allocate/free memory in userspace and get a pointer to it in return.There's a userspace/enclave space memory split for
x86_64-fortanix-unknown-sgxenclaves. It's a bit like the userspace/kernel space split, where the kernel doesn't trust pointers from userspace and is very paranoid about copying data to/from userspace.Problem
In the enclave,
User::new_uninit_bytesandUser::dropare requesting the host to alloc/dealloc memory with potentially mismatched alignment, as the enclave side is unconditionally over-aligning on allocation but not doing the same on free.User::<ByteBuffer>->alloc(_, align=8)->drop()->free(_, align=1)See: https://github.com/rust-lang/rust/blob/main/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
This min. alignment optimization was introduced in 6f7d193. See below for more details on why.
The two usercalls,
super::allocandsuper::free, are eventually handled by the host runner. They just delegate to theSystemallocator:See: https://github.com/fortanix/rust-sgx/blob/master/intel-sgx/enclave-runner-sgx/src/usercalls/mod.rs
It also appears that
enclave-runner-sgxassumes that there's no#[global_allocator]override (https://github.com/fortanix/rust-sgx/blob/master/intel-sgx/enclave-runner-sgx/src/usercalls/interface.rs#L333).For most enclave hosts running stock x86_64-unknown-linux-gnu (glibc malloc), I don't believe this mismatch is currently an issue, since posix
freeignores the alignment anyway.If you did swap in jemalloc, which does care about the dealloc alignment, then something would definitely go wrong elsewhere, as the you'd have mismatched allocators (
Systemabove vsBox<_>/Vec<_>usingGlobal).Solutions
It's not clear that we can round-up the alignment on
free, sinceUser::from_rawexists, and there's various places that call it outside std.We should probably just remove the in-enclave min. alignment until we come up with a more satisfactory solution. My guess is that the right place to do the min. alignment optimization is on enclave-runner-sgx side: https://github.com/fortanix/rust-sgx/blob/master/intel-sgx/enclave-runner-sgx/src/usercalls/mod.rs#L1596 and other places that hand memory to the SGX enclave.
Why over-align in the first place?
The min. alignment exists for performance reasons (see:
copy_from_userspace). It's highly preferable if all memory copied from userspace is at least 8 byte aligned, otherwise we have to fallback to a super slow copy routine for the unaligned prefix (and suffix).