-
Notifications
You must be signed in to change notification settings - Fork 80
Implement a capability restriction system. #89
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
Changes from all commits
7f0b181
0b28799
a3e393a
056b80a
bdc82eb
86eed01
cd44da9
5971335
8d24cf5
18a6367
a180877
26de5b9
ceaef93
a94857a
0ad3d42
254328b
57b6abb
a8d5b6c
18cf449
f37f375
d8ae296
228350f
bd262ef
ed8cbca
68a6cf0
980be06
7ef7473
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,11 +42,18 @@ using WasmForeignFunction = | |
| using WasmVmFactory = std::function<std::unique_ptr<WasmVm>()>; | ||
| using CallOnThreadFunction = std::function<void(std::function<void()>)>; | ||
|
|
||
| struct SanitizationConfig { | ||
| std::vector<std::string> argument_list; | ||
| bool is_allowlist; | ||
| }; | ||
| using AllowedCapabilitiesMap = std::unordered_map<std::string, SanitizationConfig>; | ||
|
|
||
| // Wasm execution instance. Manages the host side of the Wasm interface. | ||
| class WasmBase : public std::enable_shared_from_this<WasmBase> { | ||
| public: | ||
| WasmBase(std::unique_ptr<WasmVm> wasm_vm, std::string_view vm_id, | ||
| std::string_view vm_configuration, std::string_view vm_key); | ||
| std::string_view vm_configuration, std::string_view vm_key, | ||
| AllowedCapabilitiesMap allowed_capabilities); | ||
| WasmBase(const std::shared_ptr<WasmHandleBase> &other, WasmVmFactory factory); | ||
| virtual ~WasmBase(); | ||
|
|
||
|
|
@@ -92,6 +99,12 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> { | |
| return nullptr; | ||
| } | ||
|
|
||
| // Capability restriction (restricting/exposing the ABI). | ||
| bool capabilityAllowed(std::string capability_name) { | ||
| return allowed_capabilities_.empty() || | ||
| allowed_capabilities_.find(capability_name) != allowed_capabilities_.end(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so basically if the configuration is null, all functions are allowed, and if it is the empty list (or the meaningless list like
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But, as long as there would be no use cases for disabling all exported functions (and I don't come up with anything), this is just fine as it is.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's empty then all functions are allowed. It does feel a little unintuitive, but yeah I don't think there's any case where you would want to have all capabilities restricted. |
||
| } | ||
|
|
||
| virtual ContextBase *createVmContext() { return new ContextBase(this); } | ||
| virtual ContextBase *createRootContext(const std::shared_ptr<PluginBase> &plugin) { | ||
| return new ContextBase(this, plugin); | ||
|
|
@@ -225,6 +238,20 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> { | |
| WasmCallVoid<1> on_log_; | ||
| WasmCallVoid<1> on_delete_; | ||
|
|
||
| #define FOR_ALL_MODULE_FUNCTIONS(_f) \ | ||
| _f(validate_configuration) _f(on_vm_start) _f(on_configure) _f(on_tick) _f(on_context_create) \ | ||
| _f(on_new_connection) _f(on_downstream_data) _f(on_upstream_data) \ | ||
| _f(on_downstream_connection_close) _f(on_upstream_connection_close) _f(on_request_body) \ | ||
| _f(on_request_trailers) _f(on_request_metadata) _f(on_response_body) \ | ||
| _f(on_response_trailers) _f(on_response_metadata) _f(on_http_call_response) \ | ||
| _f(on_grpc_receive) _f(on_grpc_close) _f(on_grpc_receive_initial_metadata) \ | ||
| _f(on_grpc_receive_trailing_metadata) _f(on_queue_ready) _f(on_done) \ | ||
| _f(on_log) _f(on_delete) | ||
|
|
||
| // Capabilities which are allowed to be linked to the module. If this is empty, restriction | ||
| // is not enforced. | ||
| AllowedCapabilitiesMap allowed_capabilities_; | ||
|
|
||
| std::shared_ptr<WasmHandleBase> base_wasm_handle_; | ||
|
|
||
| // Used by the base_wasm to enable non-clonable thread local Wasm(s) to be constructed. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: @PiotrSikora we should have a new Wasm result like
Unauthorizedas WASI'sacces Permission denied.(hopefully in the next ABI ). https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#variants-1