Discussion:
Creating new ROM sessions at runtime
Georg Guba
2016-01-14 11:29:49 UTC
Permalink
Hi all,

I'm trying to start new child components from ELF binaries received at
run-time and stored in a server-local buffer. Basically, I am trying to
implement a server that can receive task descriptions and matching binaries
and then start them at run-time (disregarding security concerns for the
moment).

It appears, however, that all ROM connections must reference binaries that
are available at boot-time and adding to the ROM FS is not possible without
accessing Genode's internal code which I'd like to avoid.

So, how would I best go about creating entirely new ROM sessions at runtime?

Best regards,
Georg
Christian Helmuth
2016-01-14 16:06:11 UTC
Permalink
Hello Georg,
Post by Georg Guba
I'm trying to start new child components from ELF binaries received at
run-time and stored in a server-local buffer. Basically, I am trying to
implement a server that can receive task descriptions and matching binaries
and then start them at run-time (disregarding security concerns for the
moment).
It appears, however, that all ROM connections must reference binaries that
are available at boot-time and adding to the ROM FS is not possible without
accessing Genode's internal code which I'd like to avoid.
So, how would I best go about creating entirely new ROM sessions at runtime?
The first idea that comes to my mind is: Implement a ROM server
"elf_rom", which stores the retrieved ELF binaries in dataspaces
allocated from its RAM session. Afterwards setup the routing in your
init config for all "children" of your "parent" to "elf_rom" like
follows

<route>
..
<service name="ROM"> <child name="elf_rom_server"/> </service>
..
</route>

This may need two special precautions. First, you may need a nested
init instance which is configured with the route above. Second, you
may need some exceptions from the rule above if elf_rom_server does
not provide ROMs for "parent" and its shared libraries (if used) like

<service name="ROM" label="parent"> <parent/> </service>

Greets
--
Christian Helmuth
Genode Labs

http://www.genode-labs.com/ · http://genode.org/
https://twitter.com/GenodeLabs · /ˈdʒiː.nəʊd/

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Norman Feske
2016-01-14 17:11:24 UTC
Permalink
Hi Georg,
Post by Christian Helmuth
Post by Georg Guba
I'm trying to start new child components from ELF binaries received at
run-time and stored in a server-local buffer. Basically, I am trying to
implement a server that can receive task descriptions and matching binaries
and then start them at run-time (disregarding security concerns for the
moment).
The first idea that comes to my mind is: Implement a ROM server
"elf_rom", which stores the retrieved ELF binaries in dataspaces
allocated from its RAM session.
As long as your executable binary is statically linked, the problem can
be solved in an easier way: When creating a subsystem by constructing a
'Child' object, you have to pass a dataspace capability for the ELF
binary. You can simply allocate a new RAM dataspace (i.e., creating an
'Attached_ram_dataspace'), copy the ELF binary into the dataspace and
pass the dataspace capability to the constructor of the 'Child'. There
is no need to create a ROM server.

However, if you want to start dynamically linked executables, the child
component will initially start the dynamic linker, which, in turn,
requests the executable binary along with the needed shared libraries as
ROM sessions. Your server would need to respond to those requests by
handing out ROM-session capabilities. As an example for this approach, I
recommend you to look at the loader [1], which seems to be similar to
the server you are building.

[1]
https://github.com/genodelabs/genode/tree/master/repos/os/src/server/loader

Cheers
Norman
--
Dr.-Ing. Norman Feske
Genode Labs

http://www.genode-labs.com · http://genode.org

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Georg Guba
2016-01-18 18:16:15 UTC
Permalink
Hi Norman and Christian,

thank you both for your answers! I actually got Norman's approach working
using a slightly modified version of the demo's launchpad. With this
launchpad, all I have to do is load incoming binaries into an
Attached_ram_dataspace as Norman said.

diff --git a/repos/demo/include/launchpad/launchpad.h
b/repos/demo/include/launchpad/launchpad.h
index 9aa0ed5..2e319f8 100644
--- a/repos/demo/include/launchpad/launchpad.h
+++ b/repos/demo/include/launchpad/launchpad.h
@@ -268,7 +268,9 @@ class Launchpad
Genode::Allocator *alloc) { }

Launchpad_child *start_child(const char *prg_name, unsigned long quota,
- Genode::Dataspace_capability config_ds);
+ Genode::Dataspace_capability config_ds,
+ Genode::Dataspace_capability binary_ds =
+ Genode::Dataspace_capability());

/**
* Exit child and close all its sessions
diff --git a/repos/demo/src/lib/launchpad/launchpad.cc
b/repos/demo/src/lib/launchpad/launchpad.cc
index d60ad51..2fde521 100644
--- a/repos/demo/src/lib/launchpad/launchpad.cc
+++ b/repos/demo/src/lib/launchpad/launchpad.cc
@@ -186,7 +186,8 @@ void Launchpad::process_config()

Launchpad_child *Launchpad::start_child(const char *filename,
unsigned long ram_quota,
- Genode::Dataspace_capability
config_ds)
+ Genode::Dataspace_capability
config_ds,
+ Genode::Dataspace_capability
binary_ds)
{
printf("starting %s with quota %lu\n", filename, ram_quota);

@@ -212,19 +213,27 @@ Launchpad_child *Launchpad::start_child(const char
*filename,
/* lookup executable elf binary */
Dataspace_capability file_cap;
Rom_session_capability rom_cap;
- try {
- /*
- * When creating a ROM connection for a non-existing file, the
- * constructor of 'Rom_connection' throws a 'Parent::Service_denied'
- * exception.
- */
- Rom_connection rom(filename, unique_name);
- rom.on_destruction(Rom_connection::KEEP_OPEN);
- rom_cap = rom.cap();
- file_cap = rom.dataspace();
- } catch (...) {
- printf("Error: Could not access file \"%s\" from ROM service.\n",
filename);
- return 0;
+ if (binary_ds == Genode::Dataspace_capability())
+ {
+ /* invalid dataspace, look up in file */
+ try {
+ /*
+ * When creating a ROM connection for a non-existing file, the
+ * constructor of 'Rom_connection' throws a 'Parent::Service_denied'
+ * exception.
+ */
+ Rom_connection rom(filename, unique_name);
+ rom.on_destruction(Rom_connection::KEEP_OPEN);
+ rom_cap = rom.cap();
+ file_cap = rom.dataspace();
+ } catch (...) {
+ printf("Error: Could not access file \"%s\" from ROM service.\n",
filename);
+ return 0;
+ }
+ }
+ else
+ {
+ file_cap = binary_ds;
}

/* create ram session for child with some of our own quota */
Post by Norman Feske
Hi Georg,
Post by Christian Helmuth
Post by Georg Guba
I'm trying to start new child components from ELF binaries received at
run-time and stored in a server-local buffer. Basically, I am trying to
implement a server that can receive task descriptions and matching
binaries
Post by Christian Helmuth
Post by Georg Guba
and then start them at run-time (disregarding security concerns for the
moment).
The first idea that comes to my mind is: Implement a ROM server
"elf_rom", which stores the retrieved ELF binaries in dataspaces
allocated from its RAM session.
As long as your executable binary is statically linked, the problem can
be solved in an easier way: When creating a subsystem by constructing a
'Child' object, you have to pass a dataspace capability for the ELF
binary. You can simply allocate a new RAM dataspace (i.e., creating an
'Attached_ram_dataspace'), copy the ELF binary into the dataspace and
pass the dataspace capability to the constructor of the 'Child'. There
is no need to create a ROM server.
However, if you want to start dynamically linked executables, the child
component will initially start the dynamic linker, which, in turn,
requests the executable binary along with the needed shared libraries as
ROM sessions. Your server would need to respond to those requests by
handing out ROM-session capabilities. As an example for this approach, I
recommend you to look at the loader [1], which seems to be similar to
the server you are building.
[1]
https://github.com/genodelabs/genode/tree/master/repos/os/src/server/loader
Cheers
Norman
--
Dr.-Ing. Norman Feske
Genode Labs
http://www.genode-labs.com · http://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
GeschÀftsfÌhrer: Dr.-Ing. Norman Feske, Christian Helmuth
------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
Loading...