-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What to do about cross-Store
calls?
#958
Comments
Maybe, with the introduction of |
Ok so from our discussion on the call today, the answer here appears to be "disallow this", so we'll need to look into guarding all call-sites and such to ensure cross-store objects cannot be mixed at runtime. |
Lots of internals in the wasmtime-{jit,runtime} crates are highly unsafe, so it's up to the `wasmtime` API crate to figure out how to make it safe. One guarantee we need to provide is that values never cross between stores. For example you can't take a function in one store and move it over into a different instance in a different store. This dynamic check can't be performed at compile time and it's up to `wasmtime` to do the check itself. This adds a number of checks, but not all of them, to the codebase for now. This primarily adds checks around instantiation, globals, and tables. The main hole in this is functions, where you can pass in arguments or return values that are not from the right store. For now though we can't compile modules with `anyref` parameters/returns anyway, so we should be good. Eventually when that is supported we'll need to put the guards in place. Closes bytecodealliance#958
Lots of internals in the wasmtime-{jit,runtime} crates are highly unsafe, so it's up to the `wasmtime` API crate to figure out how to make it safe. One guarantee we need to provide is that values never cross between stores. For example you can't take a function in one store and move it over into a different instance in a different store. This dynamic check can't be performed at compile time and it's up to `wasmtime` to do the check itself. This adds a number of checks, but not all of them, to the codebase for now. This primarily adds checks around instantiation, globals, and tables. The main hole in this is functions, where you can pass in arguments or return values that are not from the right store. For now though we can't compile modules with `anyref` parameters/returns anyway, so we should be good. Eventually when that is supported we'll need to put the guards in place. Closes bytecodealliance#958
* Disallow values to cross stores Lots of internals in the wasmtime-{jit,runtime} crates are highly unsafe, so it's up to the `wasmtime` API crate to figure out how to make it safe. One guarantee we need to provide is that values never cross between stores. For example you can't take a function in one store and move it over into a different instance in a different store. This dynamic check can't be performed at compile time and it's up to `wasmtime` to do the check itself. This adds a number of checks, but not all of them, to the codebase for now. This primarily adds checks around instantiation, globals, and tables. The main hole in this is functions, where you can pass in arguments or return values that are not from the right store. For now though we can't compile modules with `anyref` parameters/returns anyway, so we should be good. Eventually when that is supported we'll need to put the guards in place. Closes #958 * Clarify how values test they come from stores * Allow null anyref to initialize tables
In reviewing some code today I started wondering what would happen if you started mixing
Store
values and instances together. For example you can create twoInstance
objects in twoStore
objects, what would happen when they're linked?The concrete things I know of today we have to worry about are:
Compiler
shared state in aStore
. This notably contains two fields:signatures
is aStore
-local registry of all known wasm signatures, mapping them to an index for signature checks duringcall_indirect
. This is actually memory unsafe today because if you mix twoStore
objects then two different signatures could get the same shared index, meaningcall_indirect
could call the wrong thing.trap_registry
is also aStore
-local registry of information about traps. While I don't think this is related to memory safety it does mean that if you're calling code in one instance but started in another the trap in the second instance won't be resolved correctly and we'll get the wrong trap information out of it.Store
that I've looked at too too deeply.I started implementing a fix where we'd simply reject linking instances together if they come from two different
Store
values, but this is also a problem with anyVal::FuncRef
getting stored in a table across instances. Especially with reference types this gets really hairy to guard, so I don't think it'll be easy to simply block access at all entry points.The only fix I can think of is to have a truly global map for all this, but it feels bad to have a truly global ever-expanding map that's never deallocated from. I think we'll want to figure out a way to remove items from the map at least when a
Store
is dropped (maybe sooner?). In any case wanted to make sure there was an open issue for this!The text was updated successfully, but these errors were encountered: