Closed lukewagner closed 4 years ago
Have you considered the case of nested defer calls? Eg, what happens when the following adapter code is run:
(@interface func (export "foobar")
defer-call-export "free"
)
(@interface implement (import "foobar")
defer-call-export "foobar"
)
I assume deferred calls would create a new "scope" with its own LIFO defer stack.
As the explainer is currently written, with only defer-call-export
, the export that is called is necessarily an export of the core wasm module (just as call-export
can only synchronously call an export of the core wasm module), and since core wasm doesn't have the defer-call-export
instruction, nested defer calls are not possible.
There's a separate topic that should be discussed in a separate issue of adding a call
instruction that allows one adapter function to call another adapter function (in a limited, non-recursive manner). This would raise the question of having a defer-call
, which would then raise the nested-defer issue you've raised here. That might be a good reason to avoid having a defer-call
.
Actually, if you export memory then you export it. It is optional to use the interface types
On Wed, Sep 4, 2019 at 12:10 PM Luke Wagner notifications@github.com wrote:
@lukewagner commented on this pull request.
In proposals/interface-types/Explainer.md https://github.com/WebAssembly/interface-types/pull/63#discussion_r320927554 :
@@ -346,7 +369,8 @@ used in the same adapter function: arg.get $str string-to-memory "mem" "malloc" call-export "frob_"
- memory-to-string "mem" "free"
As answered above: only from the core module, not the adapted module. The core module is 100% encapsulated by the adapted module, so there is no issue, I think. There's also no other way, that I know of, if we don't want to change core wasm semantics.
— You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub https://github.com/WebAssembly/interface-types/pull/63?email_source=notifications&email_token=AAQAXUG5ULQ4JJH2GGPKBG3QIAB3LA5CNFSM4ISIFDW2YY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCDVPPWI#discussion_r320927554, or mute the thread https://github.com/notifications/unsubscribe-auth/AAQAXUGDSPKG33LKUB6J7LTQIAB3LANCNFSM4ISIFDWQ .
-- Francis McCabe SWE
@fgmccabe There seems to be some confusion here, so let me try to be more clear: if an interface adapter custom section is present and the host implements Interface Types, than an export from the core module only shows up as an export from the adapted module if it is explicitly re-exported via the adapter. The adapted module is the only module the outside world sees with the core module an encapsulated implementation detail.
I understand that. However, someone can still access the wasm module ignoring the interface adapters. If they do, or even without that, they can directly access the now-shared memory. Or, am I missing something? Francis
On Wed, Sep 4, 2019 at 2:19 PM Luke Wagner notifications@github.com wrote:
@fgmccabe https://github.com/fgmccabe There seems to be some confusion here, so let me try to be more clear: if an interface adapter custom section is present and the host implements Interface Types, than an export from the core module only shows up as an export from the adapted module if it is explicitly re-exported via the adapter. The adapted module is the only module the outside world sees with the core module an encapsulated implementation detail.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WebAssembly/interface-types/pull/63?email_source=notifications&email_token=AAQAXUEKCSYM3EWIG56UBM3QIAQ5PA5CNFSM4ISIFDW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD55ATGI#issuecomment-528091545, or mute the thread https://github.com/notifications/unsubscribe-auth/AAQAXUCTMLQRHVLJ7T46SFLQIAQ5PANCNFSM4ISIFDWQ .
-- Francis McCabe SWE
However, someone can still access the wasm module ignoring the interface adapters.
How? Walk me through the specific way you're thinking of where you can run a wasm module and ignore the interface adapters.
I can think of a couple ways to do it, I just don't think they're problems. Off the top of my head:
3) is probably the most problematic, but least probable because it relies on a host that ignores the adapters. If the host implements interface types at instantiate time there's no room to do it.
What happens when a wasm module references another wasm module and claims it does not need the help of interface adapters? (C++ talking to C++ e.g.) Dynamic linking etc. I want to be able to access a credit card processing module without giving it my memory (or my allocator) The only way that this may work is if interfaces are 'optional but enforced'; i.e., a host is non-conforming if it can understand interface adapters but allows them to be ignored.
On Wed, Sep 4, 2019 at 2:40 PM Jacob Gravelle notifications@github.com wrote:
However, someone can still access the wasm module ignoring the interface adapters.
How? Walk me through the specific way you're thinking of where you can run a wasm module and ignore the interface adapters.
I can think of a couple ways to do it, I just don't think they're problems. Off the top of my head:
- you run two modules in a host that doesn't support interface types.
- you polyfill it, and that hides the export, and there's no problem
- you don't, so the ABIs don't line up and the module either fails to execute or fails to instantiate
- you run a module in a host that supports interface types but does sneaky things with the boundaries. This was already a problem because you don't trust your host, and your host can do much worse things to mess with you
- you download a 3rd party module, include it in your application in a host that doesn't support interface types, and subvert the expected interface by providing your own polyfill that doesn't hide exports. This is equivalent to dynamic linking with an undocumented ABI. It's subject to break, but works at the moment. You can read memory in ways the library author didn't intend.
3) is probably the most problematic, but least probable because it relies on a host that ignores the adapters. If the host implements interface types at instantiate time there's no room to do it.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WebAssembly/interface-types/pull/63?email_source=notifications&email_token=AAQAXUDBQE3SP2C4FNLWK4LQIATONA5CNFSM4ISIFDW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD55CJXA#issuecomment-528098524, or mute the thread https://github.com/notifications/unsubscribe-auth/AAQAXUG3H5AC3GNFKWZWJPLQIATONANCNFSM4ISIFDWQ .
-- Francis McCabe SWE
I think there's some confusion here as to what threat model wasm is supposed to guard against.
AFAICT, there is nothing that WebAssembly can (or should) do to protect against misuse by a malicious host. Even if we added a "you are not allowed to use the export directly" boolean field, malicious hosts could always manually edit that field out before compiling (or just plain ingore that field).
My understanding of interface types was that they would provide two types of security:
Both of those can be enforced as long as a host links adapted modules imports to adapted module exports, and doesn't link bare module imports/exports together. Making sure the host handles these cases correctly doesn't seem like something that could or should be enforced by the language.
EDIT: Never mind. I misunderstood what @fgmccabe was saying.
I think what it comes down to is what is the "default" linking model we want wasm to have.
The status quo so far is that nothing is shared between modules unless the host explicitly make it so.
The esm-integration proposal assumes that everything a module exports is accessible to other modules.
Interface types want some things (eg malloc/free) to be exported to the host, but not to other modules, which conflicts with esm-integration.
I'm not sure how to resolve this. Though I'm thinking even the esm-integration model should probably have some way to differentiate between things you want to export to the host, and things you want to export to importing modules.
As a follow-up from some offline discussion: I think the source of the confusion here is resolved by the observation that, once a host has implemented the interface types feature, when an interface adapter custom section is present in a module:
(This is briefly covered in the walkthrough which explicitly notes that the greeting_
and mem
core exports do not show up in the adapted module's exports.)
As a corollary to (2), adding a single @interface
definition will cause all core imports/exports to be hidden by default, requiring explicit re-export (perhaps with some syntactic sugar to explicitly request core imports/exports be present in the adapted module by default).
As discussed in #60 and the video call today.