lucet icon indicating copy to clipboard operation
lucet copied to clipboard

Add public API to get type index for a given function signature

Open shravanrn opened this issue 6 years ago • 5 comments

Context This is part of a series of bugs that I spoke to @tyler @pchickey about. We are currently using Lucet to sandbox libraries in C++ applications. The idea behind this is that using a wasm sandboxed version of the library allows ensuring that a memory safety issue in the library does not automatically result in a memory safety vulnerability in the full application. One of the consumers of this work is the Firefox web browser.

Problem As explained in more detail in issue #280 , library sandboxing allows host calls via the WASM function indirection tables. However, the wasm indirection tables require both the function pointer as well as the type index tied to that function signature. Unfortunately all APIs that handle type signatures are currently internal and so the application has no way to find the correct type index.

Actions Please let me know your thoughts on this. If this sounds good, please also let me know if this is a change that can happen internally or if it would be better if a work on a patch that can be accepted?

shravanrn avatar Sep 05 '19 05:09 shravanrn

If I understand correctly, you want to be able to add a function to the Wasm table, which means you need a function pointer and the signature index (the func and ty members of TableElement from lucet-module). The function pointer you provide yourself, but you need to be able to find a matching signature in the ModuleData in order to get the signature index.

How about a higher-level interface for writing a function to a table? For example:

impl Instance {
    fn write_table(&mut self, table_idx: u32, func_idx: u32, fptr: usize, sig: Signature) 
        -> Result<(), Error>;
}

This would attempt to look up the signature's index, and fail if it is not found. Otherwise, it would write the function pointer along with the signature index into the requested table slot.

Then, we could also offer a lower-level interface that exposed the signature lookup and assignment directly, in case you knew you had a bunch of functions with the same signature.

acfoltzer avatar Sep 05 '19 21:09 acfoltzer

The high level interface looks great! I would go as far as saying just the high level version probably suffices for our use case. We do need the ability to clear a slot as well... But I figure this could probably be accomplished by writing a null pointer to the table via the above function.

Separately, I was just thinking that such an interface would also require the runtime to expose an API that allows

  • reserving some slots that can be used for writing in this manner
  • returns the range of currently available slots that can be used for writing

shravanrn avatar Sep 06 '19 17:09 shravanrn

@acfoltzer - Just following up about the above?

shravanrn avatar Sep 15 '19 20:09 shravanrn

@shravanrn I think the two extensions you propose would fall pretty naturally out of implementing full support for mutable tables under the reference types proposal. You'd be able to import a table in the module definition, and would be free to mutate that from outside the guest. Does that sound suitable?

acfoltzer avatar Sep 16 '19 16:09 acfoltzer

Yup, that sounds reasonable.

The only clarification from my side is that, I think the reference types proposal allow us to add and use "new" tables in code, right? But, we specifically need these APIs for the existing function indirection table. This is needed because the code generated by lucet/cranelift is hardcoded to use this table for indirect function calls. But if this is covered by the implementation of tables for reference types, I think we are all set :smiley:

shravanrn avatar Sep 16 '19 21:09 shravanrn