commit 20abcefd185d72ecc55e87ff78f8f784d927653d Author: Emery Hemingway Date: Sat Apr 25 16:08:45 2020 +0530 Init/sandbox: always route "ld.lib.so" ROM to parent A livelock may occur if init router the "ld.lib.so" ROM request of a child to another child, and the child providing the ROM interacts with Init during the creation of the session. diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc index 5361665eac..fa09cca31a 100644 --- a/repos/os/src/lib/sandbox/child.cc +++ b/repos/os/src/lib/sandbox/child.cc @@ -448,6 +448,8 @@ Sandbox::Child::Route Sandbox::Child::resolve_session_request(Service::Name const &service_name, Session_label const &label) { + auto no_filter = [] (Service &) -> bool { return false; }; + /* check for "config" ROM request */ if (service_name == Rom_session::service_name() && label.last_element() == "config") { @@ -498,9 +500,20 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name, label == _unique_name && _unique_name != _binary_name) return resolve_session_request(service_name, _binary_name); - /* supply binary as dynamic linker if '' */ - if (!_use_ld && service_name == Rom_session::service_name() && label == "ld.lib.so") - return resolve_session_request(service_name, _binary_name); + /* + * Check for the "ld.lib.so" ROM request + */ + if (service_name == Rom_session::service_name() && label == "ld.lib.so") { + if (_use_ld) { + /* forward request to parent */ + return Route { + find_service(_parent_services, Rom_session::service_name(), no_filter), + Session_label("ld.lib.so"), Session::Diag { false} }; + } else { + /* supply binary as dynamic linker if '' */ + return resolve_session_request(service_name, _binary_name); + } + } /* check for "session_requests" ROM request */ if (service_name == Rom_session::service_name() @@ -541,8 +554,6 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name, Session::Diag const target_diag { target.attribute_value("diag", false) }; - auto no_filter = [] (Service &) -> bool { return false; }; - if (target.has_type("parent")) { try { commit ce74d9bb7740f14b362e72adcf8ac42e36693468 Author: Emery Hemingway Date: Sat Apr 25 17:10:03 2020 +0530 init/sandbox: support Apply routing rules to a child from a node at the top-level of a sandbox config, unless the corresponding start node has as node. If neither are present routes are taken from as a fallback. Unlike the and the rules are checked by labels prefixed by child name, so may contain child-specific rules. diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc index fa09cca31a..85389474ef 100644 --- a/repos/os/src/lib/sandbox/child.cc +++ b/repos/os/src/lib/sandbox/child.cc @@ -523,16 +523,21 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name, try { Xml_node route_node = _default_route_accessor.default_route(); + route_node = _routes_accessor.routes(route_node); try { route_node = _start_node->xml().sub_node("route"); } catch (...) { } + Xml_node service_node = route_node.sub_node(); + /* is processed with the "«child» -> " prefix */ + bool skip_prefix = route_node.type() != "routes"; + for (; ; service_node = service_node.next()) { bool service_wildcard = service_node.has_type("any-service"); - if (!service_node_matches(service_node, label, name(), service_name)) + if (!service_node_matches(service_node, label, name(), service_name, skip_prefix)) continue; Xml_node target = service_node.sub_node(); @@ -736,6 +741,7 @@ Sandbox::Child::Child(Env &env, Report_update_trigger &report_update_trigger, Xml_node start_node, Default_route_accessor &default_route_accessor, + Routes_accessor &routes_accessor, Default_caps_accessor &default_caps_accessor, Name_registry &name_registry, Ram_quota ram_limit, @@ -753,6 +759,7 @@ Sandbox::Child::Child(Env &env, _list_element(this), _start_node(_alloc, start_node), _default_route_accessor(default_route_accessor), + _routes_accessor(routes_accessor), _default_caps_accessor(default_caps_accessor), _ram_limit_accessor(ram_limit_accessor), _cap_limit_accessor(cap_limit_accessor), diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h index 4dd2803417..8e84e9bf75 100644 --- a/repos/os/src/lib/sandbox/child.h +++ b/repos/os/src/lib/sandbox/child.h @@ -52,6 +52,14 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup struct Default_route_accessor : Interface { virtual Xml_node default_route() = 0; }; struct Default_caps_accessor : Interface { virtual Cap_quota default_caps() = 0; }; + struct Routes_accessor : Interface + { + virtual Xml_node routes(Xml_node _default) + { + return _default; + } + }; + template struct Resource_limit_accessor : Interface { @@ -98,6 +106,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup bool const _use_ld = _start_node->xml().attribute_value("ld", true); Default_route_accessor &_default_route_accessor; + Routes_accessor &_routes_accessor; Default_caps_accessor &_default_caps_accessor; Ram_limit_accessor &_ram_limit_accessor; Cap_limit_accessor &_cap_limit_accessor; @@ -475,6 +484,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup Report_update_trigger &report_update_trigger, Xml_node start_node, Default_route_accessor &default_route_accessor, + Routes_accessor &route_accessor, Default_caps_accessor &default_caps_accessor, Name_registry &name_registry, Ram_quota ram_limit, diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc index 28b60c491f..30d0f2dfc1 100644 --- a/repos/os/src/lib/sandbox/library.cc +++ b/repos/os/src/lib/sandbox/library.cc @@ -23,6 +23,7 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer, ::Sandbox::Child::Default_route_accessor, + ::Sandbox::Child::Routes_accessor, ::Sandbox::Child::Default_caps_accessor, ::Sandbox::Child::Ram_limit_accessor, ::Sandbox::Child::Cap_limit_accessor @@ -52,6 +53,8 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer, Constructible _default_route { }; + Constructible _routes { }; + Cap_quota _default_caps { 0 }; unsigned _child_cnt = 0; @@ -140,6 +143,12 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer, : Xml_node(""); } + /** + * Routes_accessor interface + */ + Xml_node routes(Xml_node _default) override { + return _routes.constructed() ? _routes->xml() : _default; } + /** * Default_caps_accessor interface */ @@ -314,6 +323,9 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config) _default_route.construct(_heap, config.sub_node("default-route")); } catch (...) { } + try { _routes.construct(_heap, config.sub_node("routes")); } + catch (...) { } + _default_caps = Cap_quota { 0 }; try { _default_caps = Cap_quota { config.sub_node("default") @@ -404,7 +416,7 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config) Child &child = *new (_heap) Child(_env, _heap, *_verbose, Child::Id { ++_child_cnt }, _state_reporter, - start_node, *this, *this, _children, + start_node, *this, *this, *this, _children, Ram_quota { avail_ram.value - used_ram.value }, Cap_quota { avail_caps.value - used_caps.value }, *this, *this, prio_levels, affinity_space, diff --git a/repos/os/src/lib/sandbox/utils.h b/repos/os/src/lib/sandbox/utils.h index 7afcaebf00..36aab737f2 100644 --- a/repos/os/src/lib/sandbox/utils.h +++ b/repos/os/src/lib/sandbox/utils.h @@ -59,7 +59,8 @@ namespace Sandbox { inline bool service_node_matches(Xml_node const service_node, Session_label const &label, Child_policy::Name const &child_name, - Service::Name const &service_name) + Service::Name const &service_name, + bool skip_child_prefix = true) { bool const service_matches = service_node.has_type("any-service") || @@ -98,8 +99,9 @@ namespace Sandbox { if (!route_depends_on_child_provided_label) return true; - char const * const scoped_label = skip_label_prefix( - child_name.string(), label.string()); + char const * const scoped_label = skip_child_prefix + ? skip_label_prefix(child_name.string(), label.string()) + : label.string(); if (!scoped_label) return false;