1439 lines
49 KiB
Diff
1439 lines
49 KiB
Diff
From bf2613eb22091125c0aff894e580063dac5e2bff Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Mon, 6 Apr 2020 16:32:13 +0530
|
|
Subject: [PATCH 01/16] ld: support for loading read-only segments
|
|
|
|
---
|
|
repos/base/src/lib/ldso/include/file.h | 24 ++++++++++++++++++--
|
|
repos/base/src/lib/ldso/include/region_map.h | 10 ++++++++
|
|
2 files changed, 32 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/repos/base/src/lib/ldso/include/file.h b/repos/base/src/lib/ldso/include/file.h
|
|
index 1c9ce53ca3..6688f0edd2 100644
|
|
--- a/repos/base/src/lib/ldso/include/file.h
|
|
+++ b/repos/base/src/lib/ldso/include/file.h
|
|
@@ -34,6 +34,9 @@ namespace Linker {
|
|
|
|
static inline bool is_rw(Elf::Phdr const &ph) {
|
|
return ((ph.p_flags & PF_MASK) == (PF_R | PF_W)); }
|
|
+
|
|
+ static inline bool is_ro(Elf::Phdr const &ph) {
|
|
+ return ((ph.p_flags & PF_MASK) == PF_R); }
|
|
}
|
|
|
|
|
|
@@ -280,15 +283,21 @@ struct Linker::Elf_file : File
|
|
else if (is_rw(*ph))
|
|
load_segment_rw(*ph, i);
|
|
|
|
+ else if (is_ro(*ph))
|
|
+ load_segment_ro(*ph);
|
|
+
|
|
else {
|
|
- error("LD: Non-RW/RX segment");
|
|
+ auto X = ph->p_flags & PF_X ? "X" : "-";
|
|
+ auto W = ph->p_flags & PF_W ? "W" : "-";
|
|
+ auto R = ph->p_flags & PF_R ? "R" : "-";
|
|
+ error("LD: unhandled ", X,W,R, " segment at file offset ", Hex(ph->p_offset));
|
|
throw Invalid_file();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
- * Map read-only segment
|
|
+ * Map read-execute-only segment
|
|
*/
|
|
void load_segment_rx(Elf::Phdr const &p)
|
|
{
|
|
@@ -318,6 +327,17 @@ struct Linker::Elf_file : File
|
|
env.rm().detach(src);
|
|
}
|
|
|
|
+ /**
|
|
+ * Map read-only segment
|
|
+ */
|
|
+ void load_segment_ro(Elf::Phdr const &p)
|
|
+ {
|
|
+ Region_map::r()->attach_readonly(rom_cap,
|
|
+ trunc_page(p.p_vaddr) + reloc_base,
|
|
+ round_page(p.p_memsz),
|
|
+ trunc_page(p.p_offset));
|
|
+ }
|
|
+
|
|
/**
|
|
* Unmap segements, RM regions, and free allocated dataspaces
|
|
*/
|
|
diff --git a/repos/base/src/lib/ldso/include/region_map.h b/repos/base/src/lib/ldso/include/region_map.h
|
|
index 78d2c7033d..f17d6dfec0 100644
|
|
--- a/repos/base/src/lib/ldso/include/region_map.h
|
|
+++ b/repos/base/src/lib/ldso/include/region_map.h
|
|
@@ -130,6 +130,16 @@ class Linker::Region_map
|
|
[&] () { _env.upgrade(Parent::Env::pd(), "ram_quota=8K"); });
|
|
}
|
|
|
|
+ Local_addr attach_readonly(Dataspace_capability ds, addr_t local_addr,
|
|
+ size_t size = 0, off_t offset = 0)
|
|
+ {
|
|
+ return retry<Genode::Out_of_ram>(
|
|
+ [&] () {
|
|
+ return _rm.attach(ds, size, offset, true, local_addr - _base, false, false);
|
|
+ },
|
|
+ [&] () { _env.upgrade(Parent::Env::pd(), "ram_quota=8K"); });
|
|
+ }
|
|
+
|
|
void detach(Local_addr local_addr) { _rm.detach((addr_t)local_addr - _base); }
|
|
};
|
|
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 525ab24c481acdf9bb784cac36e663a20084b55b Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Sat, 25 Apr 2020 17:10:03 +0530
|
|
Subject: [PATCH 02/16] 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.
|
|
---
|
|
repos/os/src/lib/sandbox/child.cc | 12 +++++++++++-
|
|
repos/os/src/lib/sandbox/child.h | 10 ++++++++++
|
|
repos/os/src/lib/sandbox/library.cc | 14 +++++++++++++-
|
|
repos/os/src/lib/sandbox/utils.h | 8 +++++---
|
|
4 files changed, 39 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
|
index e321df61fd..d25e3d9683 100644
|
|
--- a/repos/os/src/lib/sandbox/child.cc
|
|
+++ b/repos/os/src/lib/sandbox/child.cc
|
|
@@ -487,17 +487,25 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
|
Session::Label(), Session::Diag{false} };
|
|
|
|
try {
|
|
+ /* Lookup route in <default-route>… */
|
|
Xml_node route_node = _default_route_accessor.default_route();
|
|
+ /* …unless <routes> is present… */
|
|
+ route_node = _routes_accessor.routes(route_node);
|
|
try {
|
|
+ /* …otherwise use <child><route>. */
|
|
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();
|
|
@@ -705,6 +713,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,
|
|
@@ -722,6 +731,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 2c213e662c..81836a2045 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;
|
|
@@ -473,6 +482,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;
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 16106e96b1cf7639b050097b131b3be3cdbcf739 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Fri, 29 May 2020 18:42:57 +0530
|
|
Subject: [PATCH 03/16] Use 128-byte strings for session labels
|
|
|
|
Sixty-four bytes is insufficient for Nix store paths.
|
|
---
|
|
repos/base/include/base/child.h | 8 ++++----
|
|
repos/base/include/base/shared_object.h | 2 +-
|
|
repos/base/src/lib/ldso/include/file.h | 2 +-
|
|
repos/libports/src/lib/libc/internal/types.h | 2 +-
|
|
repos/libports/src/lib/libc/kernel.cc | 2 +-
|
|
repos/os/src/lib/sandbox/child.h | 1 -
|
|
6 files changed, 8 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h
|
|
index 8c7b33a9d9..3bd6483547 100644
|
|
--- a/repos/base/include/base/child.h
|
|
+++ b/repos/base/include/base/child.h
|
|
@@ -44,9 +44,9 @@ namespace Genode {
|
|
*/
|
|
struct Genode::Child_policy
|
|
{
|
|
- typedef String<64> Name;
|
|
- typedef String<64> Binary_name;
|
|
- typedef String<64> Linker_name;
|
|
+ typedef String<128> Name;
|
|
+ typedef String<128> Binary_name;
|
|
+ typedef String<128> Linker_name;
|
|
|
|
virtual ~Child_policy() { }
|
|
|
|
@@ -407,7 +407,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|
|
|
Id_space<Parent::Client>::Id const _client_id;
|
|
|
|
- typedef String<64> Label;
|
|
+ typedef String<128> Label;
|
|
|
|
Args const _args;
|
|
|
|
diff --git a/repos/base/include/base/shared_object.h b/repos/base/include/base/shared_object.h
|
|
index f4dd1622fe..7ffe5fa34c 100644
|
|
--- a/repos/base/include/base/shared_object.h
|
|
+++ b/repos/base/include/base/shared_object.h
|
|
@@ -128,7 +128,7 @@ class Genode::Dynamic_linker
|
|
struct Object_info
|
|
{
|
|
/* name of shared library, or "binary" for the main program */
|
|
- typedef String<64> Name;
|
|
+ typedef String<128> Name;
|
|
Name name;
|
|
|
|
Rom_dataspace_capability ds_cap;
|
|
diff --git a/repos/base/src/lib/ldso/include/file.h b/repos/base/src/lib/ldso/include/file.h
|
|
index 6688f0edd2..e763264eee 100644
|
|
--- a/repos/base/src/lib/ldso/include/file.h
|
|
+++ b/repos/base/src/lib/ldso/include/file.h
|
|
@@ -101,7 +101,7 @@ struct Linker::Elf_file : File
|
|
Ram_dataspace_capability ram_cap[Phdr::MAX_PHDR];
|
|
bool const loaded;
|
|
|
|
- typedef String<64> Name;
|
|
+ typedef String<128> Name;
|
|
|
|
Rom_dataspace_capability _rom_dataspace(Name const &name)
|
|
{
|
|
diff --git a/repos/libports/src/lib/libc/internal/types.h b/repos/libports/src/lib/libc/internal/types.h
|
|
index 233da10b47..afaee3f8d7 100644
|
|
--- a/repos/libports/src/lib/libc/internal/types.h
|
|
+++ b/repos/libports/src/lib/libc/internal/types.h
|
|
@@ -23,7 +23,7 @@ namespace Libc {
|
|
using namespace Genode;
|
|
|
|
typedef Genode::uint64_t uint64_t;
|
|
- typedef String<64> Binary_name;
|
|
+ typedef String<128> Binary_name;
|
|
}
|
|
|
|
#endif /* _LIBC__INTERNAL__TYPES_H_ */
|
|
diff --git a/repos/libports/src/lib/libc/kernel.cc b/repos/libports/src/lib/libc/kernel.cc
|
|
index ac208b223e..3b81be01a9 100644
|
|
--- a/repos/libports/src/lib/libc/kernel.cc
|
|
+++ b/repos/libports/src/lib/libc/kernel.cc
|
|
@@ -364,7 +364,7 @@ void Libc::Kernel::_clone_state_from_parent()
|
|
|
|
/* clone RW segment of a shared library or the binary */
|
|
if (node.type() == "rw") {
|
|
- typedef String<64> Name;
|
|
+ typedef String<128> Name;
|
|
Name const name = node.attribute_value("name", Name());
|
|
|
|
/*
|
|
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
|
index 81836a2045..f7b41ddd5b 100644
|
|
--- a/repos/os/src/lib/sandbox/child.h
|
|
+++ b/repos/os/src/lib/sandbox/child.h
|
|
@@ -128,7 +128,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
|
throw Missing_name_attribute();
|
|
}
|
|
|
|
- typedef String<64> Name;
|
|
Name const _unique_name { _name_from_xml(_start_node->xml()) };
|
|
|
|
static Binary_name _binary_from_xml(Xml_node start_node,
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 3f38eacb25348a811f37ce267323253b1941cad2 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Wed, 4 Nov 2020 11:03:49 +0100
|
|
Subject: [PATCH 04/16] init/sandbox: do not parse <parent-provides> if
|
|
<routes> is present
|
|
|
|
---
|
|
repos/os/src/lib/sandbox/library.cc | 124 +++++++++++++++++++---------
|
|
1 file changed, 85 insertions(+), 39 deletions(-)
|
|
|
|
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
|
|
index 30d0f2dfc1..caa9840ea6 100644
|
|
--- a/repos/os/src/lib/sandbox/library.cc
|
|
+++ b/repos/os/src/lib/sandbox/library.cc
|
|
@@ -184,47 +184,93 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
|
|
|
void Genode::Sandbox::Library::_update_parent_services_from_config(Xml_node const &config)
|
|
{
|
|
- Xml_node const node = config.has_sub_node("parent-provides")
|
|
- ? config.sub_node("parent-provides")
|
|
- : Xml_node("<empty/>");
|
|
-
|
|
- /* remove services that are no longer present in config */
|
|
- _parent_services.for_each([&] (Parent_service &service) {
|
|
-
|
|
- Service::Name const name = service.name();
|
|
-
|
|
- bool obsolete = true;
|
|
+ if (config.has_sub_node("routes")) {
|
|
+ if (config.has_sub_node("parent-provides"))
|
|
+ warning("ignoring <parent-provides> and parsing <routes> instead");
|
|
+
|
|
+ Xml_node const node = config.sub_node("routes");
|
|
+
|
|
+ /* remove services that are no longer present in config */
|
|
+ _parent_services.for_each([&] (Parent_service &service) {
|
|
+
|
|
+ Service::Name const name = service.name();
|
|
+
|
|
+ bool obsolete = true;
|
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
|
+ if (obsolete && name == service.attribute_value("name", Service::Name())) {
|
|
+ obsolete = !service.has_sub_node("parent"); }});
|
|
+
|
|
+ if (obsolete)
|
|
+ service.abandon();
|
|
+ });
|
|
+
|
|
+ /* used to prepend the list of new parent services with title */
|
|
+ bool first_log = true;
|
|
+
|
|
+ /* register new services */
|
|
node.for_each_sub_node("service", [&] (Xml_node service) {
|
|
- if (name == service.attribute_value("name", Service::Name())) {
|
|
- obsolete = false; }});
|
|
-
|
|
- if (obsolete)
|
|
- service.abandon();
|
|
- });
|
|
-
|
|
- /* used to prepend the list of new parent services with title */
|
|
- bool first_log = true;
|
|
-
|
|
- /* register new services */
|
|
- node.for_each_sub_node("service", [&] (Xml_node service) {
|
|
-
|
|
- Service::Name const name = service.attribute_value("name", Service::Name());
|
|
-
|
|
- bool registered = false;
|
|
- _parent_services.for_each([&] (Parent_service const &service) {
|
|
- if (service.name() == name)
|
|
- registered = true; });
|
|
-
|
|
- if (!registered) {
|
|
- new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
|
- if (_verbose->enabled()) {
|
|
- if (first_log)
|
|
- log("parent provides");
|
|
- log(" service \"", name, "\"");
|
|
- first_log = false;
|
|
+ if (service.has_sub_node("child")) return;
|
|
+
|
|
+ Service::Name const name = service.attribute_value("name", Service::Name());
|
|
+
|
|
+ bool registered = false;
|
|
+ _parent_services.for_each([&] (Parent_service const &service) {
|
|
+ if (service.name() == name)
|
|
+ registered = true; });
|
|
+
|
|
+ if (!registered) {
|
|
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
|
+ if (_verbose->enabled()) {
|
|
+ if (first_log)
|
|
+ log("parent provides");
|
|
+ log(" service \"", name, "\"");
|
|
+ first_log = false;
|
|
+ }
|
|
}
|
|
- }
|
|
- });
|
|
+ });
|
|
+ } else {
|
|
+ Xml_node const node = config.has_sub_node("parent-provides")
|
|
+ ? config.sub_node("parent-provides")
|
|
+ : Xml_node("<empty/>");
|
|
+
|
|
+ /* remove services that are no longer present in config */
|
|
+ _parent_services.for_each([&] (Parent_service &service) {
|
|
+
|
|
+ Service::Name const name = service.name();
|
|
+
|
|
+ bool obsolete = true;
|
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
|
+ if (name == service.attribute_value("name", Service::Name())) {
|
|
+ obsolete = false; }});
|
|
+
|
|
+ if (obsolete)
|
|
+ service.abandon();
|
|
+ });
|
|
+
|
|
+ /* used to prepend the list of new parent services with title */
|
|
+ bool first_log = true;
|
|
+
|
|
+ /* register new services */
|
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
|
+
|
|
+ Service::Name const name = service.attribute_value("name", Service::Name());
|
|
+
|
|
+ bool registered = false;
|
|
+ _parent_services.for_each([&] (Parent_service const &service) {
|
|
+ if (service.name() == name)
|
|
+ registered = true; });
|
|
+
|
|
+ if (!registered) {
|
|
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
|
+ if (_verbose->enabled()) {
|
|
+ if (first_log)
|
|
+ log("parent provides");
|
|
+ log(" service \"", name, "\"");
|
|
+ first_log = false;
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+ }
|
|
}
|
|
|
|
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From ef28369a1e6ba0f8910da3a6cb757f9e5ec334ad Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Wed, 4 Nov 2020 20:02:03 +0100
|
|
Subject: [PATCH 05/16] init/sandbox: simplify routing
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Remove <default-route>, <any-service>, and <any-child> configuration
|
|
options.
|
|
|
|
Allow label rewriting with <parent prefix="…" suffix="…">
|
|
and <child name="…" prefix="…" suffix="…">.
|
|
|
|
Routes are now selected by longest match rather than first match.
|
|
---
|
|
repos/os/src/lib/sandbox/child.cc | 131 ++++++++++------------------
|
|
repos/os/src/lib/sandbox/child.h | 3 -
|
|
repos/os/src/lib/sandbox/library.cc | 12 +--
|
|
repos/os/src/lib/sandbox/utils.h | 57 ++++++------
|
|
4 files changed, 76 insertions(+), 127 deletions(-)
|
|
|
|
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
|
index d25e3d9683..46aa22411c 100644
|
|
--- a/repos/os/src/lib/sandbox/child.cc
|
|
+++ b/repos/os/src/lib/sandbox/child.cc
|
|
@@ -11,6 +11,7 @@
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
+#include <os/session_policy.h>
|
|
#include <vm_session/vm_session.h>
|
|
|
|
/* local includes */
|
|
@@ -486,105 +487,65 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
|
return Route { _session_requester.service(),
|
|
Session::Label(), Session::Diag{false} };
|
|
|
|
- try {
|
|
- /* Lookup route in <default-route>… */
|
|
- Xml_node route_node = _default_route_accessor.default_route();
|
|
- /* …unless <routes> is present… */
|
|
- route_node = _routes_accessor.routes(route_node);
|
|
- try {
|
|
- /* …otherwise use <child><route>. */
|
|
- 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, skip_prefix))
|
|
- continue;
|
|
-
|
|
- Xml_node target = service_node.sub_node();
|
|
- for (; ; target = target.next()) {
|
|
-
|
|
- /*
|
|
- * Determine session label to be provided to the server
|
|
- *
|
|
- * By default, the client's identity (accompanied with the a
|
|
- * client-provided label) is presented as session label to the
|
|
- * server. However, the target node can explicitly override the
|
|
- * client's identity by a custom label via the 'label'
|
|
- * attribute.
|
|
- */
|
|
- typedef String<Session_label::capacity()> Label;
|
|
- Label const target_label =
|
|
- target.attribute_value("label", Label(label.string()));
|
|
-
|
|
- Session::Diag const
|
|
- target_diag { target.attribute_value("diag", false) };
|
|
-
|
|
- auto no_filter = [] (Service &) -> bool { return false; };
|
|
-
|
|
- if (target.has_type("parent")) {
|
|
-
|
|
- try {
|
|
- return Route { find_service(_parent_services, service_name, no_filter),
|
|
- target_label, target_diag };
|
|
- } catch (Service_denied) { }
|
|
+ {
|
|
+ Xml_node service_node("<deny/>");
|
|
+ Xml_node routes_node = _routes_accessor.routes(service_node);
|
|
+ Xml_node_label_score best_score;
|
|
+
|
|
+ routes_node.for_each_sub_node([&] (Xml_node const &node) {
|
|
+ if (service_node_matches(node, label, service_name)) {
|
|
+ Xml_node_label_score score(node, label);
|
|
+ if (score.stronger(best_score)
|
|
+ || service_node.has_type("deny")) {
|
|
+ best_score = score;
|
|
+ service_node = node;
|
|
}
|
|
+ }
|
|
+ });
|
|
|
|
- if (target.has_type("local")) {
|
|
+ if (service_node.has_type("deny")) {
|
|
+ warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
|
|
+ throw Service_denied();
|
|
+ }
|
|
|
|
- try {
|
|
- return Route { find_service(_local_services, service_name, no_filter),
|
|
- target_label, target_diag };
|
|
- } catch (Service_denied) { }
|
|
- }
|
|
+ for (Xml_node target_node = service_node.sub_node(); ;
|
|
+ target_node = target_node.next()) {
|
|
|
|
- if (target.has_type("child")) {
|
|
+ Session_label the_label_part_of_label(skip_label_prefix(name().string(), label.string()));
|
|
+ if (the_label_part_of_label == "") the_label_part_of_label = label;
|
|
|
|
- typedef Name_registry::Name Name;
|
|
- Name server_name = target.attribute_value("name", Name());
|
|
- server_name = _name_registry.deref_alias(server_name);
|
|
+ auto target_label = Sandbox::target_label(
|
|
+ target_node, name(), the_label_part_of_label);
|
|
|
|
- auto filter_server_name = [&] (Routed_service &s) -> bool {
|
|
- return s.child_name() != server_name; };
|
|
+ Session::Diag const
|
|
+ target_diag { target_node.attribute_value("diag", false) };
|
|
|
|
- try {
|
|
- return Route { find_service(_child_services, service_name, filter_server_name),
|
|
- target_label, target_diag };
|
|
+ auto no_filter = [] (Service &) -> bool { return false; };
|
|
|
|
- } catch (Service_denied) { }
|
|
- }
|
|
+ if (target_node.has_type("parent"))
|
|
+ return Route { find_service(_parent_services, service_name, no_filter),
|
|
+ target_label, target_diag };
|
|
|
|
- if (target.has_type("any-child")) {
|
|
+ if (target_node.has_type("local"))
|
|
+ return Route { find_service(_local_services, service_name, no_filter),
|
|
+ target_label, target_diag };
|
|
|
|
- if (is_ambiguous(_child_services, service_name)) {
|
|
- error(name(), ": ambiguous routes to "
|
|
- "service \"", service_name, "\"");
|
|
- throw Service_denied();
|
|
- }
|
|
- try {
|
|
- return Route { find_service(_child_services, service_name, no_filter),
|
|
- target_label, target_diag };
|
|
+ if (target_node.has_type("child")) {
|
|
|
|
- } catch (Service_denied) { }
|
|
- }
|
|
+ typedef Name_registry::Name Name;
|
|
+ Name server_name = target_node.attribute_value("name", Name());
|
|
+ server_name = _name_registry.deref_alias(server_name);
|
|
|
|
- if (!service_wildcard) {
|
|
- warning(name(), ": lookup for service \"", service_name, "\" failed");
|
|
- throw Service_denied();
|
|
- }
|
|
+ auto filter_server_name = [&] (Routed_service &s) -> bool {
|
|
+ return s.child_name() != server_name; };
|
|
|
|
- if (target.last())
|
|
- break;
|
|
+ return Route { find_service(_child_services, service_name, filter_server_name),
|
|
+ target_label, target_diag };
|
|
}
|
|
+
|
|
+ if (target_node.last()) break;
|
|
}
|
|
- } catch (Xml_node::Nonexistent_sub_node) { }
|
|
+ }
|
|
|
|
warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
|
|
throw Service_denied();
|
|
@@ -712,7 +673,6 @@ Sandbox::Child::Child(Env &env,
|
|
Id id,
|
|
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,
|
|
@@ -730,7 +690,6 @@ Sandbox::Child::Child(Env &env,
|
|
_report_update_trigger(report_update_trigger),
|
|
_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),
|
|
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
|
index f7b41ddd5b..fd254d7f49 100644
|
|
--- a/repos/os/src/lib/sandbox/child.h
|
|
+++ b/repos/os/src/lib/sandbox/child.h
|
|
@@ -49,7 +49,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
|
*/
|
|
struct Id { unsigned value; };
|
|
|
|
- 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
|
|
@@ -105,7 +104,6 @@ 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;
|
|
@@ -480,7 +478,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
|
Id id,
|
|
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,
|
|
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
|
|
index caa9840ea6..7b4e72c60e 100644
|
|
--- a/repos/os/src/lib/sandbox/library.cc
|
|
+++ b/repos/os/src/lib/sandbox/library.cc
|
|
@@ -22,7 +22,6 @@
|
|
#include <heartbeat.h>
|
|
|
|
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,
|
|
@@ -134,15 +133,6 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
|
_children.report_state(xml, detail);
|
|
}
|
|
|
|
- /**
|
|
- * Default_route_accessor interface
|
|
- */
|
|
- Xml_node default_route() override
|
|
- {
|
|
- return _default_route.constructed() ? _default_route->xml()
|
|
- : Xml_node("<empty/>");
|
|
- }
|
|
-
|
|
/**
|
|
* Routes_accessor interface
|
|
*/
|
|
@@ -462,7 +452,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, *this, _children,
|
|
+ start_node, *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 36aab737f2..639a4be4dd 100644
|
|
--- a/repos/os/src/lib/sandbox/utils.h
|
|
+++ b/repos/os/src/lib/sandbox/utils.h
|
|
@@ -58,12 +58,9 @@ 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,
|
|
- bool skip_child_prefix = true)
|
|
+ Service::Name const &service_name)
|
|
{
|
|
bool const service_matches =
|
|
- service_node.has_type("any-service") ||
|
|
(service_node.has_type("service") &&
|
|
service_node.attribute_value("name", Service::Name()) == service_name);
|
|
|
|
@@ -72,7 +69,6 @@ namespace Sandbox {
|
|
|
|
typedef String<Session_label::capacity()> Label;
|
|
|
|
- char const *unscoped_attr = "unscoped_label";
|
|
char const *label_last_attr = "label_last";
|
|
|
|
bool const route_depends_on_child_provided_label =
|
|
@@ -81,34 +77,13 @@ namespace Sandbox {
|
|
service_node.has_attribute("label_suffix") ||
|
|
service_node.has_attribute(label_last_attr);
|
|
|
|
- if (service_node.has_attribute(unscoped_attr)) {
|
|
-
|
|
- /*
|
|
- * If an 'unscoped_label' attribute is provided, don't consider any
|
|
- * scoped label attribute.
|
|
- */
|
|
- if (route_depends_on_child_provided_label)
|
|
- warning("service node contains both scoped and unscoped label attributes");
|
|
-
|
|
- return label == service_node.attribute_value(unscoped_attr, Label());
|
|
- }
|
|
-
|
|
if (service_node.has_attribute(label_last_attr))
|
|
return service_node.attribute_value(label_last_attr, Label()) == label.last_element();
|
|
|
|
if (!route_depends_on_child_provided_label)
|
|
return true;
|
|
|
|
- char const * const scoped_label = skip_child_prefix
|
|
- ? skip_label_prefix(child_name.string(), label.string())
|
|
- : label.string();
|
|
-
|
|
- if (!scoped_label)
|
|
- return false;
|
|
-
|
|
- Session_label const session_label(scoped_label);
|
|
-
|
|
- return !Xml_node_label_score(service_node, session_label).conflict();
|
|
+ return !Xml_node_label_score(service_node, label).conflict();
|
|
}
|
|
|
|
|
|
@@ -131,6 +106,34 @@ namespace Sandbox {
|
|
return cnt > 1;
|
|
}
|
|
|
|
+
|
|
+ /*
|
|
+ * Determine session label to be provided to the server
|
|
+ *
|
|
+ * By default, the client's identity (accompanied with the a
|
|
+ * client-provided label) is presented as session label to the
|
|
+ * server. However, the target node can explicitly override the
|
|
+ * client's identity by a custom label via the 'label' attribute or
|
|
+ * by specifying a 'prefix' and 'suffix attributes.
|
|
+ */
|
|
+ typedef String<Session_label::capacity()> Label;
|
|
+ inline Label target_label(Xml_node const node,
|
|
+ Child_policy::Name const &child_name,
|
|
+ Session_label const &label)
|
|
+ {
|
|
+ if (node.has_attribute("label"))
|
|
+ return Session_label(node.attribute_value("label", Label()).string());
|
|
+
|
|
+ Label head = node.attribute_value("prefix", Label(child_name.string()));
|
|
+ Label tail = node.attribute_value("suffix", Label(child_name == label ? "" : label));
|
|
+
|
|
+ if (head == "") return tail;
|
|
+ if (tail == "") return head;
|
|
+
|
|
+ return Label(prefixed_label(head, tail).string());
|
|
+ }
|
|
+
|
|
+
|
|
/**
|
|
* Find service with certain values in given registry
|
|
*
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 79ae552230809f62e1717a08f5ce9a63c044abf9 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Sat, 7 Nov 2020 08:37:29 +0100
|
|
Subject: [PATCH 06/16] core: log ROM requests with affirmative "diag" flag
|
|
|
|
---
|
|
repos/base/src/core/include/rom_session_component.h | 12 ++++++++++--
|
|
1 file changed, 10 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/repos/base/src/core/include/rom_session_component.h b/repos/base/src/core/include/rom_session_component.h
|
|
index c584701f5f..2c93302e14 100644
|
|
--- a/repos/base/src/core/include/rom_session_component.h
|
|
+++ b/repos/base/src/core/include/rom_session_component.h
|
|
@@ -35,12 +35,20 @@ namespace Genode {
|
|
{
|
|
/* extract label */
|
|
Session_label const label = label_from_args(args);
|
|
+ auto const name = label.last_element();
|
|
+
|
|
+ /* extract diag flag */
|
|
+ bool diag = session_diag_from_args(args).enabled;
|
|
|
|
/* find ROM module for trailing label element */
|
|
- Rom_module const * rom = rom_fs.find(label.last_element().string());
|
|
- if (rom)
|
|
+ Rom_module const * rom = rom_fs.find(name.string());
|
|
+
|
|
+ if (rom) {
|
|
+ if (diag) log("serve ROM \"", name, "\" to \"", label, "\"");
|
|
return *rom;
|
|
+ }
|
|
|
|
+ error("ROM not found for ", args);
|
|
throw Service_denied();
|
|
}
|
|
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 0e1ea49ea6ce4f85e2e30a01aa5ace7928b20267 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Sat, 7 Nov 2020 11:23:03 +0100
|
|
Subject: [PATCH 07/16] base: fail on label truncation
|
|
|
|
---
|
|
repos/base/include/base/session_label.h | 27 ++++++++++++++++++++++---
|
|
repos/base/include/util/arg_string.h | 6 ++++++
|
|
2 files changed, 30 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/repos/base/include/base/session_label.h b/repos/base/include/base/session_label.h
|
|
index d5e752d120..85034904e5 100644
|
|
--- a/repos/base/include/base/session_label.h
|
|
+++ b/repos/base/include/base/session_label.h
|
|
@@ -16,10 +16,14 @@
|
|
#define _INCLUDE__BASE__SESSION_LABEL_H_
|
|
|
|
#include <base/snprintf.h>
|
|
+#include <base/log.h>
|
|
#include <util/arg_string.h>
|
|
#include <util/string.h>
|
|
|
|
-namespace Genode { struct Session_label; }
|
|
+namespace Genode {
|
|
+ struct Session_label;
|
|
+ class Label_overflow : Exception { };
|
|
+}
|
|
|
|
struct Genode::Session_label : String<160>
|
|
{
|
|
@@ -33,6 +37,8 @@ struct Genode::Session_label : String<160>
|
|
using String = String<capacity()>;
|
|
using String::String;
|
|
|
|
+ /* TODO: String::String can still truncate and break labels */
|
|
+
|
|
/**
|
|
* Copy constructor
|
|
*
|
|
@@ -41,7 +47,13 @@ struct Genode::Session_label : String<160>
|
|
*/
|
|
template <size_t N>
|
|
Session_label(Genode::String<N> const &other)
|
|
- : Genode::String<160>(other) { }
|
|
+ : Genode::String<160>(other)
|
|
+ {
|
|
+ if (length() < other.length()) {
|
|
+ error(__func__, " overflow - «", other, "»");
|
|
+ throw Label_overflow();
|
|
+ }
|
|
+ }
|
|
|
|
Session_label last_element() const
|
|
{
|
|
@@ -90,8 +102,13 @@ namespace Genode {
|
|
inline Session_label label_from_args(char const *args)
|
|
{
|
|
char buf[Session_label::capacity()];
|
|
- Arg_string::find_arg(args, "label").string(buf, sizeof(buf), "");
|
|
+ auto arg = Arg_string::find_arg(args, "label");
|
|
+ if (Session_label::capacity() <= arg.length()) {
|
|
+ error(__func__, " overflow - «", (char const *)args, "»");
|
|
+ throw Label_overflow();
|
|
+ }
|
|
|
|
+ arg.string(buf, sizeof(buf), "");
|
|
return Session_label(Cstring(buf));
|
|
}
|
|
|
|
@@ -103,6 +120,10 @@ namespace Genode {
|
|
String<N2> const &label)
|
|
{
|
|
String<N1 + N2 + 4> const prefixed_label(prefix, " -> ", label);
|
|
+ if (Session_label::capacity() <= prefixed_label.length()) {
|
|
+ error(__func__, " overflow - «", prefix, "» - «", label, "»");
|
|
+ throw Label_overflow();
|
|
+ }
|
|
return Session_label(prefixed_label);
|
|
}
|
|
}
|
|
diff --git a/repos/base/include/util/arg_string.h b/repos/base/include/util/arg_string.h
|
|
index 610fbb16b3..48777e0c2a 100644
|
|
--- a/repos/base/include/util/arg_string.h
|
|
+++ b/repos/base/include/util/arg_string.h
|
|
@@ -114,6 +114,12 @@ class Genode::Arg
|
|
|
|
inline bool valid() const { return _key; }
|
|
|
|
+ size_t length() const
|
|
+ {
|
|
+ return _value.type() == Token::STRING
|
|
+ ? _value.len() - 2 : _value.len();
|
|
+ }
|
|
+
|
|
unsigned long ulong_value(unsigned long default_value) const
|
|
{
|
|
unsigned long value = 0;
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 2c193324a6702e123c8cafabda45c30c7ca09257 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Sat, 7 Nov 2020 13:49:41 +0100
|
|
Subject: [PATCH 08/16] init: log error when configuration cannot be parsed
|
|
|
|
---
|
|
repos/os/src/init/main.cc | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/repos/os/src/init/main.cc b/repos/os/src/init/main.cc
|
|
index 7b69c95721..f1c1a1435a 100644
|
|
--- a/repos/os/src/init/main.cc
|
|
+++ b/repos/os/src/init/main.cc
|
|
@@ -47,6 +47,10 @@ struct Init::Main : Sandbox::State_handler
|
|
_config.update();
|
|
|
|
Xml_node const config = _config.xml();
|
|
+ if (config.has_type("empty")) {
|
|
+ error("failed to parse config ROM");
|
|
+ return;
|
|
+ };
|
|
|
|
bool reporter_enabled = false;
|
|
config.with_sub_node("report", [&] (Xml_node report) {
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 5d07e900e3c7f0fe507844bccc5f168bad046a3c Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Sat, 28 Nov 2020 14:00:49 +0100
|
|
Subject: [PATCH 09/16] Do not default Child::binary_name() to Child::name()
|
|
|
|
---
|
|
repos/base/include/base/child.h | 2 +-
|
|
repos/base/src/core/main.cc | 2 ++
|
|
repos/os/src/lib/sandbox/child.h | 1 +
|
|
3 files changed, 4 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h
|
|
index 3bd6483547..a00e59e3a4 100644
|
|
--- a/repos/base/include/base/child.h
|
|
+++ b/repos/base/include/base/child.h
|
|
@@ -58,7 +58,7 @@ struct Genode::Child_policy
|
|
/**
|
|
* ROM module name of the binary to start
|
|
*/
|
|
- virtual Binary_name binary_name() const { return name(); }
|
|
+ virtual Binary_name binary_name() const = 0;
|
|
|
|
/**
|
|
* ROM module name of the dynamic linker
|
|
diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc
|
|
index d480585221..7acacf0ffd 100644
|
|
--- a/repos/base/src/core/main.cc
|
|
+++ b/repos/base/src/core/main.cc
|
|
@@ -145,6 +145,8 @@ class Core_child : public Child_policy
|
|
|
|
Name name() const override { return "init"; }
|
|
|
|
+ Binary_name binary_name() const override { return "init"; }
|
|
+
|
|
Route resolve_session_request(Service::Name const &name,
|
|
Session_label const &label) override
|
|
{
|
|
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
|
index fd254d7f49..036e7f8fc2 100644
|
|
--- a/repos/os/src/lib/sandbox/child.h
|
|
+++ b/repos/os/src/lib/sandbox/child.h
|
|
@@ -594,6 +594,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
|
****************************/
|
|
|
|
Child_policy::Name name() const override { return _unique_name; }
|
|
+ Child_policy::Binary_name binary_name() const override { return _binary_name; }
|
|
|
|
Pd_session &ref_pd() override { return _env.pd(); }
|
|
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 0ac7fd14676b451e11b74c9e66f7de265b3ee4e6 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Thu, 3 Dec 2020 12:19:10 +0100
|
|
Subject: [PATCH 10/16] vfs: create missing root directories for writeable
|
|
sessions
|
|
|
|
This is the expected behavior.
|
|
---
|
|
repos/os/src/server/vfs/main.cc | 47 ++++++++++++++++++++++++++++++---
|
|
1 file changed, 43 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc
|
|
index b780b1fdd7..358afd28a9 100644
|
|
--- a/repos/os/src/server/vfs/main.cc
|
|
+++ b/repos/os/src/server/vfs/main.cc
|
|
@@ -841,6 +841,41 @@ class Vfs_server::Root : public Genode::Root_component<Session_component>,
|
|
Genode::Signal_transmitter(_reactivate_handler).submit();
|
|
}
|
|
|
|
+ /**
|
|
+ * Open a directory, ensuring all parent directories exists.
|
|
+ */
|
|
+ void _create_session_dir(Path const &path)
|
|
+ {
|
|
+ using namespace Genode;
|
|
+ typedef Vfs::Directory_service::Opendir_result Result;
|
|
+
|
|
+ Vfs_handle *handle { nullptr };
|
|
+ Vfs::File_system &vfs = _vfs_env.root_dir();
|
|
+
|
|
+ switch (vfs.opendir(path.string(), true, &handle, _vfs_heap)) {
|
|
+ case Result::OPENDIR_OK:
|
|
+ handle->close();
|
|
+ return;
|
|
+ case Result::OPENDIR_ERR_NODE_ALREADY_EXISTS:
|
|
+ if (vfs.directory(path.string())) return;
|
|
+ break;
|
|
+ case Result::OPENDIR_ERR_LOOKUP_FAILED: {
|
|
+ Path parent = path;
|
|
+ parent.strip_last_element();
|
|
+ _create_session_dir(parent.string());
|
|
+ auto res = vfs.opendir(path.string(), true, &handle, _vfs_heap);
|
|
+ if (res == Result::OPENDIR_OK) {
|
|
+ handle->close();
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ default: break;
|
|
+ }
|
|
+
|
|
+ error("cannot create session root at ", path);
|
|
+ throw Service_denied();
|
|
+ }
|
|
+
|
|
protected:
|
|
|
|
Session_component *_create_session(const char *args) override
|
|
@@ -916,10 +951,14 @@ class Vfs_server::Root : public Genode::Root_component<Session_component>,
|
|
}
|
|
|
|
/* check if the session root exists */
|
|
- if (!((session_root == "/")
|
|
- || _vfs_env.root_dir().directory(session_root.base()))) {
|
|
- error("session root '", session_root, "' not found for '", label, "'");
|
|
- throw Service_denied();
|
|
+ if (session_root != "/") {
|
|
+ if (!_vfs_env.root_dir().directory(session_root.base())) {
|
|
+ if (writeable) { _create_session_dir(session_root); }
|
|
+ else {
|
|
+ error("session root '", session_root, "' not found for '", label, "'");
|
|
+ throw Service_denied();
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
Session_component *session = new (md_alloc())
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 6842e2d0c2c784d224a9d7bc100e491545b8e5e6 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Thu, 28 Jan 2021 13:39:29 +0100
|
|
Subject: [PATCH 11/16] genode_dyn.ld: do not emit PHDR segment
|
|
|
|
Recent version of binutils check that PHDR segments are covered
|
|
by a LOAD segment. In this case the unloaded PHDR segment can be
|
|
ommited.
|
|
---
|
|
repos/base/src/ld/genode_dyn.ld | 1 -
|
|
1 file changed, 1 deletion(-)
|
|
|
|
diff --git a/repos/base/src/ld/genode_dyn.ld b/repos/base/src/ld/genode_dyn.ld
|
|
index 5fa6ddc29e..57ec92f0f6 100644
|
|
--- a/repos/base/src/ld/genode_dyn.ld
|
|
+++ b/repos/base/src/ld/genode_dyn.ld
|
|
@@ -18,7 +18,6 @@
|
|
|
|
PHDRS
|
|
{
|
|
- phdr PT_PHDR PHDRS;
|
|
interp PT_INTERP;
|
|
ro PT_LOAD;
|
|
rw PT_LOAD;
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From ff8ffb77ccf4238001abd7253c45dece86fe8983 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Wed, 3 Feb 2021 15:20:39 +0100
|
|
Subject: [PATCH 12/16] vfs: support for loading plugins by label
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Make the VFS plugin recognize <plugin label="…"/> nodes.
|
|
---
|
|
repos/os/src/lib/vfs/file_system_factory.cc | 33 ++++++++++++++++-----
|
|
1 file changed, 26 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/repos/os/src/lib/vfs/file_system_factory.cc b/repos/os/src/lib/vfs/file_system_factory.cc
|
|
index 5cdf20e8e3..1cf5d587ea 100644
|
|
--- a/repos/os/src/lib/vfs/file_system_factory.cc
|
|
+++ b/repos/os/src/lib/vfs/file_system_factory.cc
|
|
@@ -56,8 +56,16 @@ struct Vfs::Global_file_system_factory::Entry_base : Vfs::File_system_factory,
|
|
|
|
Entry_base(Fs_type_name const &name) : name(name) { }
|
|
|
|
- bool matches(Genode::Xml_node node) const {
|
|
- return node.has_type(name.string()); }
|
|
+ bool matches(Genode::Xml_node node) const
|
|
+ {
|
|
+ if (node.has_type(name.string()))
|
|
+ return true;
|
|
+
|
|
+ if (node.has_type("plugin") && node.has_attribute("load"))
|
|
+ return node.attribute("load").has_value(name.string());
|
|
+
|
|
+ return false;
|
|
+ }
|
|
};
|
|
|
|
|
|
@@ -165,14 +173,25 @@ Vfs::File_system_factory &Vfs::Global_file_system_factory::_load_factory(Vfs::En
|
|
bool Vfs::Global_file_system_factory::_probe_external_factory(Vfs::Env &env,
|
|
Genode::Xml_node node)
|
|
{
|
|
- Library_name const lib_name = _library_name(node.type());
|
|
-
|
|
try {
|
|
- _list.insert(new (env.alloc())
|
|
- External_entry(node.type().string(), _load_factory(env, lib_name)));
|
|
- return true;
|
|
+ if (node.has_type("plugin")) {
|
|
+ Library_name const lib_name = node.attribute_value("load", Library_name(""));
|
|
+
|
|
+ if (lib_name == "") {
|
|
+ error("missing \"load\" attribute at ", node);
|
|
+ return false;
|
|
+ }
|
|
|
|
+ _list.insert(new (env.alloc())
|
|
+ External_entry(lib_name.string(), _load_factory(env, lib_name)));
|
|
+ } else {
|
|
+ Library_name const lib_name = _library_name(node.type());
|
|
+
|
|
+ _list.insert(new (env.alloc())
|
|
+ External_entry(node.type().string(), _load_factory(env, lib_name)));
|
|
+ }
|
|
} catch (Factory_not_available) { return false; }
|
|
+ return true;
|
|
}
|
|
|
|
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 490fb611ceaad9ae67af35c22ac40dd65ddd7a42 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Wed, 3 Feb 2021 17:33:24 +0100
|
|
Subject: [PATCH 13/16] vfs: increase the capacity of tar ROM labels to 128
|
|
|
|
---
|
|
repos/os/src/lib/vfs/tar_file_system.h | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/repos/os/src/lib/vfs/tar_file_system.h b/repos/os/src/lib/vfs/tar_file_system.h
|
|
index d9941deb5f..fcb06a1459 100644
|
|
--- a/repos/os/src/lib/vfs/tar_file_system.h
|
|
+++ b/repos/os/src/lib/vfs/tar_file_system.h
|
|
@@ -27,7 +27,7 @@ class Vfs::Tar_file_system : public File_system
|
|
Genode::Env &_env;
|
|
Genode::Allocator &_alloc;
|
|
|
|
- typedef Genode::String<64> Rom_name;
|
|
+ typedef Genode::String<128> Rom_name;
|
|
Rom_name _rom_name;
|
|
|
|
Genode::Attached_rom_dataspace _tar_ds { _env, _rom_name.string() };
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From a9900477faf8d9d41dbe3fa59a0b40ce5cab037f Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Wed, 10 Feb 2021 13:32:42 +0100
|
|
Subject: [PATCH 14/16] Detect destroyed argument buffers at Env::session
|
|
|
|
Session request arguments are silently zeroed when their length
|
|
exceedes some buffer size.
|
|
---
|
|
repos/base/src/lib/base/component.cc | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/repos/base/src/lib/base/component.cc b/repos/base/src/lib/base/component.cc
|
|
index 568be31efb..913687ea7f 100644
|
|
--- a/repos/base/src/lib/base/component.cc
|
|
+++ b/repos/base/src/lib/base/component.cc
|
|
@@ -122,6 +122,10 @@ namespace {
|
|
Affinity const &affinity) override
|
|
{
|
|
Mutex::Guard guard(_mutex);
|
|
+ if (!args.valid_string()) {
|
|
+ error("invalid args for ", name.string(), " service request");
|
|
+ throw Service_denied();
|
|
+ }
|
|
|
|
/*
|
|
* Since we account for the backing store for session meta data on
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From d2da7f94d328336ab6ac618ff5779ae8093c5e9d Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Thu, 11 Feb 2021 14:10:50 +0100
|
|
Subject: [PATCH 15/16] Increase session arguments buffer size to 240 bytes
|
|
|
|
---
|
|
repos/base/include/parent/parent.h | 2 +-
|
|
repos/base/include/root/root.h | 2 +-
|
|
repos/base/lib/symbols/ld | 2 ++
|
|
3 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/repos/base/include/parent/parent.h b/repos/base/include/parent/parent.h
|
|
index 7379342e5b..6e94047788 100644
|
|
--- a/repos/base/include/parent/parent.h
|
|
+++ b/repos/base/include/parent/parent.h
|
|
@@ -54,7 +54,7 @@ class Genode::Parent
|
|
public:
|
|
|
|
typedef Rpc_in_buffer<64> Service_name;
|
|
- typedef Rpc_in_buffer<160> Session_args;
|
|
+ typedef Rpc_in_buffer<240> Session_args;
|
|
typedef Rpc_in_buffer<160> Upgrade_args;
|
|
|
|
struct Client : Interface { typedef Id_space<Client>::Id Id; };
|
|
diff --git a/repos/base/include/root/root.h b/repos/base/include/root/root.h
|
|
index c7e3a0c908..4fda9e341f 100644
|
|
--- a/repos/base/include/root/root.h
|
|
+++ b/repos/base/include/root/root.h
|
|
@@ -29,7 +29,7 @@ namespace Genode {
|
|
|
|
struct Genode::Root
|
|
{
|
|
- typedef Rpc_in_buffer<160> Session_args;
|
|
+ typedef Rpc_in_buffer<240> Session_args;
|
|
typedef Rpc_in_buffer<160> Upgrade_args;
|
|
|
|
virtual ~Root() { }
|
|
diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld
|
|
index 3cfbdd7466..d7603e8ca4 100644
|
|
--- a/repos/base/lib/symbols/ld
|
|
+++ b/repos/base/lib/symbols/ld
|
|
@@ -398,6 +398,8 @@ _ZThn236_N5Timer10Connection11set_timeoutEN6Genode12MicrosecondsERNS1_15Timeout_
|
|
_ZThn236_N5Timer10Connection9curr_timeEv T
|
|
_ZThn288_N5Timer10Connection11set_timeoutEN6Genode12MicrosecondsERNS1_15Timeout_handlerE T
|
|
_ZThn288_N5Timer10Connection9curr_timeEv T
|
|
+_ZThn368_N5Timer10Connection11set_timeoutEN6Genode12MicrosecondsERNS1_15Timeout_handlerE T
|
|
+_ZThn368_N5Timer10Connection9curr_timeEv T
|
|
_ZThn8_N6Genode17Timeout_scheduler14handle_timeoutENS_8DurationE T
|
|
_ZThn8_N6Genode17Timeout_schedulerD0Ev T
|
|
_ZThn8_N6Genode17Timeout_schedulerD1Ev T
|
|
--
|
|
2.30.0
|
|
|
|
|
|
From 9b1a5e00ba1fc7fccfec5ba6671c6e80e428f129 Mon Sep 17 00:00:00 2001
|
|
From: Emery Hemingway <ehmry@posteo.net>
|
|
Date: Fri, 19 Feb 2021 16:09:23 +0100
|
|
Subject: [PATCH 16/16] ldso: increase size of library names
|
|
|
|
---
|
|
repos/base/src/lib/ldso/include/config.h | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/repos/base/src/lib/ldso/include/config.h b/repos/base/src/lib/ldso/include/config.h
|
|
index 5708df0930..db9014a95b 100644
|
|
--- a/repos/base/src/lib/ldso/include/config.h
|
|
+++ b/repos/base/src/lib/ldso/include/config.h
|
|
@@ -58,7 +58,7 @@ class Linker::Config : Noncopyable
|
|
bool verbose() const { return _verbose; }
|
|
bool check_ctors() const { return _check_ctors; }
|
|
|
|
- typedef String<100> Rom_name;
|
|
+ typedef String<128> Rom_name;
|
|
|
|
/**
|
|
* Call fn for each library specified in the configuration
|
|
--
|
|
2.30.0
|
|
|