229 lines
9.4 KiB
Diff
229 lines
9.4 KiB
Diff
commit 20abcefd185d72ecc55e87ff78f8f784d927653d
|
|
Author: Emery Hemingway <ehmry@posteo.net>
|
|
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 '<start ld="no">' */
|
|
- 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 '<start ld="no">' */
|
|
+ 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 <ehmry@posteo.net>
|
|
Date: Sat Apr 25 17:10:03 2020 +0530
|
|
|
|
init/sandbox: <routes> support
|
|
|
|
Apply routing rules to a child from a <routes> node at the top-level of
|
|
a sandbox config, unless the corresponding start node has as <route>
|
|
node. If neither are present routes are taken from <default-route> as a
|
|
fallback.
|
|
|
|
Unlike the <route> and <default-route> the <routes> rules are checked by
|
|
labels prefixed by child name, so <routes> 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();
|
|
|
|
+ /* <routes> 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 <typename QUOTA>
|
|
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<Buffered_xml> _default_route { };
|
|
|
|
+ Constructible<Buffered_xml> _routes { };
|
|
+
|
|
Cap_quota _default_caps { 0 };
|
|
|
|
unsigned _child_cnt = 0;
|
|
@@ -140,6 +143,12 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
|
: Xml_node("<empty/>");
|
|
}
|
|
|
|
+ /**
|
|
+ * 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;
|