This repository was archived by the owner on Mar 24, 2022. It is now read-only.
lucet-runtime: relax TLS checks when making Instance from Vmctx#654
Closed
lucet-runtime: relax TLS checks when making Instance from Vmctx#654
Conversation
Only check that vmctx pointer matches with CURRENT_INSTANCE on creation of Vmctx, and return from a yield. This change makes it possible to use Vmctx in a block_on Future.
…ory through vmctx This test only passes because of relaxed vmctx tls restriction
Contributor
Author
|
I did this work on a branch where I had marked the block_on futures as non-Send, which is unsound. Dead end, trying again with #655 |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
In the implementation of
Vmctx, the functioninstance_from_vmctxis used frequently to access the&mut Instancecorresponding to aVmctx. Prior to this patch, that function would always check that the*const Instancepointer calculated relative to*const lucet_vmctxmatches with the instance pointer stored in the thread-localCURRENT_INSTANCErefcell.The purpose of this check is to provide some assurance that a
*const lucet_vmctxpassed in from WebAssembly has not been corrupted. It alao helps make sure that the stack-swapping machinery is behaving correctly. We do not believe it is necessary to perform this safety check at every use of Vmctx. Additionally, doing so makes it impossible to use Vmctx methods in future passed toVmctx::block_on- more on this below.Repeating this check in nearly every method call to Vmctx &self is belt-and-braces: in safe Rust there should be no way to invalidate the property of Vmctx that was already established during construction in from_raw.
CURRENT_INSTANCEis set byInstance::with_current_instance: the instance pointer is written to the refcell before swapping into the guest stack inInstance::swap_and_return, and cleared after the guest stack swaps back to the host stack.The two places it seems most critical to perform this safety check are: 1. when constructing a
Vmctx::from_raw- taking the possibly-corrupt*const lucet_vmctxpassed in from WebAssembly and turning it into aVmctx, and 2. upon returning to the guest stack from a yield, ensuring the Vmctx on the guest stack still matches the instance used byswap_and_return, even if the thread context has changed (e.g. in an async runtime).This patch factors the thread-local storage check into
instance_ensure_tlsand performs the check in only those two cases.Also, note that I removed a redundant
inst.valid_magic()assertion inVmctx::from_raw- that check is performed ininstance_from_vmctx.Testing
The most natural place where a
Vmctxis valid, butCURRENT_INSTANCEis not, is during execution of a future given toVmctx::block_on.Therefore, I added a test to the async_hostcall suite where the future given to
block_onmakes a call toVmctx::heap_mut, which is implemented in terms ofinstance_from_vmctx. Before this change, this test would fail by panicking in the tls check. With this change, the test passes and asynchronous code is able to call arbitrary Vmctx methods, e.g. to access embedding ctx or to modify the heap.