2
0
Fork 0

WiP! rom-names patch

This commit is contained in:
Ehmry - 2020-11-02 00:01:22 +01:00
parent ecf6f909a9
commit d7959b453b
3 changed files with 566 additions and 1 deletions

View File

@ -30,7 +30,7 @@ let
version = upstreamSources.lastModifiedDate;
src = upstreamSources;
nativeBuildInputs = [ expect gnumake tcl ];
patches = [ ./binary-labels.patch ];
patches = [ ./binary-labels.patch ./rom-names.patch ];
configurePhase = ''
patchShebangs ./tool
substituteInPlace repos/base/etc/tools.conf \

View File

@ -85,3 +85,28 @@ index 150640ddf3..e511897600 100644
DUMMY(int , -1, getpriority, (int, int))
DUMMY(int , -1, getrusage, (int, rusage *))
DUMMY_SILENT(uid_t , 0, getuid, (void))
commit d64e4b926c1dec39569efee89567f0575770bbd6
Author: Emery Hemingway <ehmry@posteo.net>
Date: Sun Nov 1 23:18:05 2020 +0100
libc: do not strip file paths in dlopen
Request files by verbatim path rather than shorten them to just a
filename. This is to ensure that libraries with the "/nix/store/..."
prefix are resolved correctly.
diff --git a/repos/libports/src/lib/libc/dynamic_linker.cc b/repos/libports/src/lib/libc/dynamic_linker.cc
index ba47856bed..b7aff1b869 100644
--- a/repos/libports/src/lib/libc/dynamic_linker.cc
+++ b/repos/libports/src/lib/libc/dynamic_linker.cc
@@ -78,9 +78,7 @@ void *dlopen(const char *name, int mode)
static Libc::Allocator global_alloc;
return new (global_alloc)
- Shared_object(*genode_env, global_alloc,
- name ? Genode::Path<128>(name).last_element() : nullptr, /* extract file name */
- bind, keep);
+ Shared_object(*genode_env, global_alloc, name, bind, keep);
} catch (...) {
snprintf(err_str, MAX_ERR, "Unable to open file %s\n", name);
}

View File

@ -0,0 +1,540 @@
commit adba5891acc724320c61743a6ec8694d2dc92d99
Author: Emery Hemingway <ehmry@posteo.net>
Date: Sun Nov 1 23:14:11 2020 +0100
Pass explicit ROM name in session requests
When name of a ROM in a session request is passed only as the last
element of the request label then it can be destroyed if the label
exceedes the size of the Genode::Session_label string type. This can
happen if the initial ROM name is too large or after a sufficient number
of prefixes are prepended to the label.
diff --git a/repos/base-linux/src/core/spec/linux/dataspace_component.cc b/repos/base-linux/src/core/spec/linux/dataspace_component.cc
index ad5c5c2929..45ce45333c 100644
--- a/repos/base-linux/src/core/spec/linux/dataspace_component.cc
+++ b/repos/base-linux/src/core/spec/linux/dataspace_component.cc
@@ -34,15 +34,15 @@ using namespace Genode;
Linux_dataspace::Filename Dataspace_component::_file_name(const char *args)
{
- Session_label const label = label_from_args(args);
+ auto name = rom_name_from_args(args);
Linux_dataspace::Filename fname;
- if (label.last_element().length() > sizeof(fname.buf)) {
- Genode::error("file name too long: ", label.last_element());
+ if (name.length() > sizeof(fname.buf)) {
+ Genode::error("file name too long: ", name);
throw Service_denied();
}
- copy_cstring(fname.buf, label.last_element().string(), sizeof(fname.buf));
+ copy_cstring(fname.buf, name.string(), sizeof(fname.buf));
/* only files inside the current working directory are allowed */
for (const char *c = fname.buf; *c; ++c)
diff --git a/repos/base-linux/src/core/spec/pc/dataspace_component.cc b/repos/base-linux/src/core/spec/pc/dataspace_component.cc
index d84132a596..a29b8da555 100644
--- a/repos/base-linux/src/core/spec/pc/dataspace_component.cc
+++ b/repos/base-linux/src/core/spec/pc/dataspace_component.cc
@@ -33,15 +33,15 @@ using namespace Genode;
Linux_dataspace::Filename Dataspace_component::_file_name(const char *args)
{
- Session_label const label = label_from_args(args);
+ auto name = rom_name_from_args(args);
Linux_dataspace::Filename fname;
- if (label.last_element().length() > sizeof(fname.buf)) {
- Genode::error("file name too long: ", label.last_element());
+ if (name.length() > sizeof(fname.buf)) {
+ Genode::error("file name too long: ", name);
throw Service_denied();
}
- copy_cstring(fname.buf, label.last_element().string(), sizeof(fname.buf));
+ copy_cstring(fname.buf, name.string(), sizeof(fname.buf));
/* only files inside the current working directory are allowed */
for (const char *c = fname.buf; *c; ++c)
diff --git a/repos/base/include/rom_session/connection.h b/repos/base/include/rom_session/connection.h
index ce1b9badf4..c4590ac1ed 100644
--- a/repos/base/include/rom_session/connection.h
+++ b/repos/base/include/rom_session/connection.h
@@ -39,8 +39,10 @@ struct Genode::Rom_connection : Connection<Rom_session>,
try :
Connection<Rom_session>(env,
session(env.parent(),
- "ram_quota=%ld, cap_quota=%ld, label=\"%s\"",
- RAM_QUOTA, CAP_QUOTA, label)),
+ "ram_quota=%ld, cap_quota=%ld, "
+ "name=\"%s\", label=\"%s\"",
+ RAM_QUOTA, CAP_QUOTA,
+ label, label)),
Rom_session_client(cap())
{ }
catch (...) {
diff --git a/repos/base/include/rom_session/rpc_object.h b/repos/base/include/rom_session/rpc_object.h
new file mode 100644
index 0000000000..dc9676c3a3
--- /dev/null
+++ b/repos/base/include/rom_session/rpc_object.h
@@ -0,0 +1,48 @@
+/*
+ * \brief Server-side ROM session object
+ * \author Emery Hemingway
+ * \date 2020-11-01
+ */
+
+/*
+ * Copyright (C) 2020 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#ifndef _INCLUDE__ROM_SESSION__RPC_OBJECT_H_
+#define _INCLUDE__ROM_SESSION__RPC_OBJECT_H_
+
+#include <rom_session/rom_session.h>
+#include <base/log.h>
+#include <base/rpc_server.h>
+#include <util/arg_string.h>
+
+namespace Genode {
+
+ typedef Rpc_object<Rom_session> Rom_rpc_object;
+
+ /**
+ * Extract ROM name from session arguments
+ */
+ inline Session_label rom_name_from_args(char const *args)
+ {
+ char buf[Session_label::capacity()];
+
+ Arg_string::find_arg(args, "name").string(buf, sizeof(buf), "");
+ Session_label const name{Cstring(buf)};
+
+ Arg_string::find_arg(args, "label").string(buf, sizeof(buf), "");
+ Session_label const label{Cstring(buf)};
+ Session_label const label_last = label.last_element();
+
+ if (name == "") return label_last;
+ if (name != label_last)
+ warning("ROM name mangled to \"", label, "\" from \"", name, "\"");
+ return name;
+ }
+
+}
+
+#endif /* _INCLUDE__ROM_SESSION__RPC_OBJECT_H_ */
diff --git a/repos/base/src/core/include/rom_session_component.h b/repos/base/src/core/include/rom_session_component.h
index c584701f5f..1a9e4e5bd3 100644
--- a/repos/base/src/core/include/rom_session_component.h
+++ b/repos/base/src/core/include/rom_session_component.h
@@ -17,12 +17,12 @@
#include <rom_fs.h>
#include <base/rpc_server.h>
#include <dataspace_component.h>
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
#include <base/session_label.h>
namespace Genode {
- class Rom_session_component : public Rpc_object<Rom_session>
+ class Rom_session_component : public Rom_rpc_object
{
private:
@@ -33,11 +33,11 @@ namespace Genode {
Rom_module const &_find_rom(Rom_fs &rom_fs, const char *args)
{
- /* extract label */
- Session_label const label = label_from_args(args);
+ /* extract name of ROM */
+ auto name = rom_name_from_args(args);
- /* find ROM module for trailing label element */
- Rom_module const * rom = rom_fs.find(label.last_element().string());
+ /* find ROM module */
+ Rom_module const * rom = rom_fs.find(name.string());
if (rom)
return *rom;
diff --git a/repos/os/include/init/child_policy.h b/repos/os/include/init/child_policy.h
index 544b0730c9..d614fddce1 100644
--- a/repos/os/include/init/child_policy.h
+++ b/repos/os/include/init/child_policy.h
@@ -19,7 +19,7 @@
/* Genode includes */
#include <base/rpc_server.h>
#include <base/service.h>
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
namespace Init {
class Child_policy_provide_rom_file;
@@ -79,15 +79,17 @@ class Init::Child_policy_provide_rom_file
Service *resolve_session_request_with_label(Service::Name const &name,
Session_label const &label)
{
- return (name == "ROM" && label.last_element() == _module_name)
+ return (name == Rom_session::service_name()
+ && label.last_element() == _module_name)
? &_service : nullptr;
}
Service *resolve_session_request(const char *service_name,
const char *args)
{
- return resolve_session_request_with_label(service_name,
- label_from_args(args));
+ return (service_name == Rom_session::service_name()
+ && rom_name_from_args(args) == _module_name)
+ ? &_service : nullptr;
}
};
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
index e321df61fd..cd7a971abb 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 <rom_session/rpc_object.h>
#include <vm_session/vm_session.h>
/* local includes */
@@ -463,23 +464,6 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
*/
}
- /*
- * Check for the binary's ROM request
- *
- * The binary is requested as a ROM with the child's unique
- * name ('Child_policy::binary_name' equals 'Child_policy::name').
- * If the binary name differs from the child's unique name,
- * we resolve the session request with the binary name as label.
- * Otherwise the regular routing is applied.
- */
- if (service_name == Rom_session::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 "session_requests" ROM request */
if (service_name == Rom_session::service_name()
&& label.last_element() == Session_requester::rom_name())
@@ -641,6 +625,31 @@ void Sandbox::Child::filter_session_args(Service::Name const &service,
Arg_string::remove_arg(args, "managing_system");
}
}
+
+ if (service == Rom_session::service_name()) {
+ auto rom_name = rom_name_from_args(args);
+
+ /*
+ * Check for the binary's ROM request
+ *
+ * The binary is requested as a ROM with the child's unique
+ * name ('Child_policy::binary_name' equals 'Child_policy::name').
+ * If the binary name differs from the child's unique name,
+ * we resolve the session request with the binary name as label.
+ * Otherwise the regular routing is applied.
+ */
+ if (rom_name == _unique_name && _unique_name != _binary_name)
+ Arg_string::set_arg(args, args_len, "name", _binary_name.string());
+
+ /* supply binary as dynamic linker if '<start ld="no">' */
+ else if (!_use_ld && rom_name == "ld.lib.so")
+ Arg_string::set_arg(args, args_len, "name", _binary_name.string());
+
+ /* set the ROM name before something breaks */
+ else if (rom_name == "")
+ Arg_string::set_arg(args, args_len, "name",
+ rom_name_from_args(args).last_element().string());
+ }
}
diff --git a/repos/os/src/server/cached_fs_rom/main.cc b/repos/os/src/server/cached_fs_rom/main.cc
index 9e4e4d0eee..8dfcb58d1e 100755
--- a/repos/os/src/server/cached_fs_rom/main.cc
+++ b/repos/os/src/server/cached_fs_rom/main.cc
@@ -15,7 +15,7 @@
#include <os/path.h>
#include <file_system_session/connection.h>
#include <file_system/util.h>
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
#include <region_map/client.h>
#include <rm_session/connection.h>
#include <base/attached_ram_dataspace.h>
@@ -233,24 +233,21 @@ struct Cached_fs_rom::Transfer final
};
-class Cached_fs_rom::Session_component final : public Rpc_object<Rom_session>
+class Cached_fs_rom::Session_component final : public Rom_rpc_object
{
private:
Cached_rom &_cached_rom;
Cached_rom::Guard _cache_guard { _cached_rom };
Session_space::Element _sessions_elem;
- Session_label const _label;
public:
Session_component(Cached_rom &cached_rom,
- Session_space &space, Session_space::Id id,
- Session_label const &label)
+ Session_space &space, Session_space::Id id)
:
_cached_rom(cached_rom),
- _sessions_elem(*this, space, id),
- _label(label)
+ _sessions_elem(*this, space, id)
{ }
@@ -366,8 +363,9 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler
Session_space::Id const id { pid.value };
- Session_label const label = label_from_args(args.string());
- Path const path(label.last_element().string());
+ auto const label = label_from_args(args.string());
+ auto const rom_name = rom_name_from_args(args.string());
+ Path const path(rom_name.string());
Cached_rom *rom = nullptr;
@@ -393,7 +391,7 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler
if (rom->completed()) {
/* Create new RPC object */
Session_component *session = new (heap)
- Session_component(*rom, sessions, id, label);
+ Session_component(*rom, sessions, id);
if (session_diag_from_args(args.string()).enabled)
log("deliver ROM \"", label, "\"");
env.parent().deliver_session_cap(pid, env.ep().manage(*session));
diff --git a/repos/os/src/server/dynamic_rom/main.cc b/repos/os/src/server/dynamic_rom/main.cc
index 95d4175dab..efcc92b3f1 100644
--- a/repos/os/src/server/dynamic_rom/main.cc
+++ b/repos/os/src/server/dynamic_rom/main.cc
@@ -20,7 +20,7 @@
#include <base/log.h>
#include <base/attached_rom_dataspace.h>
#include <base/attached_ram_dataspace.h>
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
#include <timer_session/connection.h>
#include <root/component.h>
@@ -221,7 +221,7 @@ class Dynamic_rom::Root : public Genode::Root_component<Session_component>
/* read name of ROM module from args */
Session_label const label = label_from_args(args);
- Session_label const module_name = label.last_element();
+ Session_label const module_name = rom_name_from_args(args);
try {
return new (md_alloc())
diff --git a/repos/os/src/server/fs_rom/main.cc b/repos/os/src/server/fs_rom/main.cc
index 2221af0363..4fbd54f3f5 100755
--- a/repos/os/src/server/fs_rom/main.cc
+++ b/repos/os/src/server/fs_rom/main.cc
@@ -13,7 +13,7 @@
*/
/* Genode includes */
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
#include <file_system_session/connection.h>
#include <file_system/util.h>
#include <os/path.h>
@@ -44,7 +44,7 @@ namespace Fs_rom {
/**
* A 'Rom_session_component' exports a single file of the file system
*/
-class Fs_rom::Rom_session_component : public Rpc_object<Rom_session>
+class Fs_rom::Rom_session_component : public Rom_rpc_object
{
private:
@@ -519,8 +519,7 @@ class Fs_rom::Rom_root : public Root_component<Fs_rom::Rom_session_component>
Rom_session_component *_create_session(const char *args) override
{
- Session_label const label = label_from_args(args);
- Session_label const module_name = label.last_element();
+ auto module_name = rom_name_from_args(args);
/* create new session for the requested file */
return new (md_alloc())
diff --git a/repos/os/src/server/iso9660/main.cc b/repos/os/src/server/iso9660/main.cc
index fa41152716..a7f0e92558 100644
--- a/repos/os/src/server/iso9660/main.cc
+++ b/repos/os/src/server/iso9660/main.cc
@@ -22,7 +22,7 @@
#include <base/attached_ram_dataspace.h>
#include <base/session_label.h>
#include <block_session/connection.h>
-#include <rom_session/rom_session.h>
+#include <rom_session/rpc_object.h>
/* local includes */
#include "iso9660.h"
@@ -78,14 +78,14 @@ class Iso::File : public File_base
{
Iso::read_file(block, _info, 0, _ds.size(), _ds.local_addr<void>());
}
-
+
~File() { destroy(_alloc, _info); }
Dataspace_capability dataspace() { return _ds.cap(); }
};
-class Iso::Rom_component : public Genode::Rpc_object<Rom_session>
+class Iso::Rom_component : public Genode::Rom_rpc_object
{
private:
@@ -156,8 +156,8 @@ class Iso::Root : public Iso::Root_component
if (ram_quota < session_size)
throw Insufficient_ram_quota();
- Session_label const label = label_from_args(args);
- copy_cstring(_path, label.last_element().string(), sizeof(_path));
+ Session_label const name = rom_name_from_args(args);
+ copy_cstring(_path, name.string(), sizeof(_path));
if (verbose)
Genode::log("Request for file ", Cstring(_path), " len ", strlen(_path));
diff --git a/repos/os/src/server/loader/main.cc b/repos/os/src/server/loader/main.cc
index d2f5240c6a..d72f3f13ee 100644
--- a/repos/os/src/server/loader/main.cc
+++ b/repos/os/src/server/loader/main.cc
@@ -18,6 +18,7 @@
#include <loader_session/loader_session.h>
#include <root/component.h>
#include <os/session_policy.h>
+#include <rom_session/rpc_object.h>
/* local includes */
#include <child.h>
@@ -73,8 +74,7 @@ class Loader::Session_component : public Rpc_object<Session>
try {
Mutex::Guard guard(_mutex);
- Session_label const label = label_from_args(args.string());
- Session_label const name = label.last_element();
+ Session_label const name = rom_name_from_args(args.string());
Rom_module &module = _rom_modules.lookup_and_lock(name.string());
diff --git a/repos/os/src/server/rom_prefetcher/main.cc b/repos/os/src/server/rom_prefetcher/main.cc
index 7f1552ff57..e3bd89fea1 100644
--- a/repos/os/src/server/rom_prefetcher/main.cc
+++ b/repos/os/src/server/rom_prefetcher/main.cc
@@ -17,6 +17,7 @@
#include <base/log.h>
#include <base/heap.h>
#include <base/attached_rom_dataspace.h>
+#include <rom_session/rpc_object.h>
#include <timer_session/connection.h>
#include <base/session_label.h>
@@ -84,11 +85,11 @@ class Rom_prefetcher::Rom_root : public Genode::Root_component<Rom_session_compo
Rom_session_component *_create_session(const char *args) override
{
- Genode::Session_label const label = Genode::label_from_args(args);
+ Genode::Session_label const name = Genode::rom_name_from_args(args);
/* create new session for the requested file */
return new (md_alloc())
- Rom_session_component(_env, label.last_element());
+ Rom_session_component(_env, name);
}
public:
diff --git a/repos/os/src/server/tar_rom/main.cc b/repos/os/src/server/tar_rom/main.cc
index 00fd032c00..7d372d89de 100755
--- a/repos/os/src/server/tar_rom/main.cc
+++ b/repos/os/src/server/tar_rom/main.cc
@@ -13,6 +13,7 @@
*/
/* Genode includes */
+#include <rom_session/rpc_object.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <base/heap.h>
@@ -32,7 +33,7 @@ namespace Tar_rom {
/**
* A 'Rom_session_component' exports a single file of the tar archive
*/
-class Tar_rom::Rom_session_component : public Rpc_object<Rom_session>
+class Tar_rom::Rom_session_component : public Rom_rpc_object
{
private:
@@ -197,8 +198,7 @@ class Tar_rom::Rom_root : public Root_component<Rom_session_component>
Rom_session_component *_create_session(const char *args) override
{
- Session_label const label = label_from_args(args);
- Session_label const module_name = label.last_element();
+ Session_label const module_name = rom_name_from_args(args);
log("connection for module '", module_name, "' requested");
/* create new session for the requested file */
diff --git a/repos/ports/src/app/gdb_monitor/rom.h b/repos/ports/src/app/gdb_monitor/rom.h
index d6163765b6..2b75bd5f51 100644
--- a/repos/ports/src/app/gdb_monitor/rom.h
+++ b/repos/ports/src/app/gdb_monitor/rom.h
@@ -19,6 +19,7 @@
#include <dataspace/client.h>
#include <root/component.h>
#include <rom_session/connection.h>
+#include <rom_session/rpc_object.h>
#include <util/arg_string.h>
@@ -35,7 +36,7 @@ namespace Gdb_monitor
/**
* ROM session backed by RAM dataspace copy of original ROM
*/
-class Gdb_monitor::Rom_session_component : public Rpc_object<Rom_session>
+class Gdb_monitor::Rom_session_component : public Rom_rpc_object
{
private:
@@ -120,12 +121,12 @@ class Gdb_monitor::Local_rom_factory : public Rom_service::Factory
Rom_session_component &create(Args const &args, Affinity) override
{
- Session_label const label = label_from_args(args.string());
+ Session_label const name = rom_name_from_args(args.string());
return *new (_alloc)
Rom_session_component(_env,
_ep,
- label.last_element().string());
+ name.string());
}
void upgrade(Rom_session_component &, Args const &) override { }