Generalize handling of PD-session arguments
On Linux, we want to attach additional attributes to processes, i.e., the chroot location, the designated UID, and GID. Instead of polluting the generic code with such Linux-specific platform details, I introduced the new 'Native_pd_args' type, which can be customized for each platform. The platform-dependent policy of init is factored out in the new 'pd_args' library. The new 'base-linux/run/lx_pd_args.run' script can be used to validate the propagation of those attributes into core. Note that this patch does not add the interpretation of the new UID and PID attributes by core. This will be subject of a follow-up patch. Related to #510.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
#include <util/string.h>
|
||||
#include <base/native_capability.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
@@ -149,6 +150,35 @@ namespace Genode {
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
class Native_pd_args
|
||||
{
|
||||
public:
|
||||
|
||||
enum { ROOT_PATH_MAX_LEN = 256 };
|
||||
|
||||
private:
|
||||
|
||||
char _root[ROOT_PATH_MAX_LEN];
|
||||
|
||||
unsigned _uid;
|
||||
unsigned _gid;
|
||||
|
||||
public:
|
||||
|
||||
Native_pd_args() : _uid(0), _gid(0) { _root[0] = 0; }
|
||||
|
||||
Native_pd_args(char const *root, unsigned uid, unsigned gid)
|
||||
:
|
||||
_uid(uid), _gid(gid)
|
||||
{
|
||||
Genode::strncpy(_root, root, sizeof(_root));
|
||||
}
|
||||
|
||||
char const *root() const { return _root; }
|
||||
unsigned uid() const { return _uid; }
|
||||
unsigned gid() const { return _gid; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */
|
||||
|
||||
100
base-linux/include/pd_session/connection.h
Normal file
100
base-linux/include/pd_session/connection.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* \brief Connection to PD service
|
||||
* \author Norman Feske
|
||||
* \date 2012-11-21
|
||||
*
|
||||
* In contrast to the generic version of 'pd_session/connection.h', the
|
||||
* Linux-specific version supplies additional argument to core's PD service:
|
||||
*
|
||||
* :'root': is the path of a chroot environment of the process
|
||||
* :'uid': is the user ID of the process
|
||||
* :'gid': is the designated group ID of the process
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PD_SESSION__CONNECTION_H_
|
||||
#define _INCLUDE__PD_SESSION__CONNECTION_H_
|
||||
|
||||
#include <pd_session/client.h>
|
||||
#include <base/connection.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Pd_connection : public Connection<Pd_session>, public Pd_session_client
|
||||
{
|
||||
private:
|
||||
|
||||
template <Genode::size_t STRING_MAX_LEN>
|
||||
struct Arg
|
||||
{
|
||||
char string[STRING_MAX_LEN];
|
||||
|
||||
Arg() { string[0] = 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert root path argument to session-construction parameter
|
||||
*/
|
||||
struct Root_arg : Arg<Native_pd_args::ROOT_PATH_MAX_LEN>
|
||||
{
|
||||
Root_arg(Native_pd_args const *args)
|
||||
{
|
||||
if (args && args->root() && args->root()[0])
|
||||
Genode::snprintf(string, sizeof(string), ", root=\"%s\"",
|
||||
args->root());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert UID argument to session-construction parameter
|
||||
*/
|
||||
struct Uid_arg : Arg<64>
|
||||
{
|
||||
Uid_arg(Native_pd_args const *args)
|
||||
{
|
||||
if (args && args->uid())
|
||||
Genode::snprintf(string, sizeof(string), ", uid=%u",
|
||||
args->uid());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert GID argument to session-construction parameter
|
||||
*/
|
||||
struct Gid_arg : Arg<64>
|
||||
{
|
||||
Gid_arg(Native_pd_args const *args)
|
||||
{
|
||||
if (args && args->gid())
|
||||
Genode::snprintf(string, sizeof(string), ", gid=%u",
|
||||
args->gid());
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param label session label
|
||||
* \param pd_args Linux-specific PD-session arguments
|
||||
*/
|
||||
Pd_connection(char const *label = "", Native_pd_args const *pd_args = 0)
|
||||
:
|
||||
Connection<Pd_session>(
|
||||
session("ram_quota=4K, label=\"%s\"%s%s%s", label,
|
||||
Root_arg(pd_args).string,
|
||||
Uid_arg(pd_args).string,
|
||||
Gid_arg(pd_args).string)),
|
||||
Pd_session_client(cap())
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__PD_SESSION__CONNECTION_H_ */
|
||||
59
base-linux/run/lx_pd_args.run
Normal file
59
base-linux/run/lx_pd_args.run
Normal file
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# \brief Test for supplying Linux-specific PD-session arguments to core
|
||||
# \author Norman Feske
|
||||
# \date 2012-11-21
|
||||
#
|
||||
|
||||
build "core init test/printf"
|
||||
|
||||
assert_spec linux
|
||||
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</default-route>
|
||||
<start name="init" uid="11">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<start name="test-printf" root="/tmp/somewhere" uid="33" gid="44">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
build_boot_image "core init test-printf"
|
||||
|
||||
#
|
||||
# The chroot to '/tmp/somewhere' is expected to fail. We just want to validate
|
||||
# that the PD-session arguments are properly propagated into core. Hence, we
|
||||
# can take the error message as exit condition of the test run.
|
||||
#
|
||||
run_genode_until {chroot path does not point to valid directory} 10
|
||||
|
||||
# keep only the lines containing the relevant core output
|
||||
grep_output {^ .*:}
|
||||
|
||||
compare_output_to {
|
||||
uid: 11
|
||||
root: /tmp/somewhere
|
||||
uid: 11
|
||||
gid: 44
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ Process::Process(Dataspace_capability elf_data_ds_cap,
|
||||
Rm_session_capability rm_session_cap,
|
||||
Parent_capability parent_cap,
|
||||
char const *name,
|
||||
char const *root)
|
||||
Native_pd_args const *pd_args)
|
||||
:
|
||||
_pd(name, root),
|
||||
_pd(name, pd_args),
|
||||
_cpu_session_client(Cpu_session_capability()),
|
||||
_rm_session_client(Rm_session_capability())
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Genode {
|
||||
unsigned long _pid;
|
||||
char _label[LABEL_MAX_LEN];
|
||||
char _root[ROOT_PATH_MAX_LEN];
|
||||
unsigned _uid;
|
||||
unsigned _gid;
|
||||
Parent_capability _parent;
|
||||
Rpc_entrypoint *_ds_ep;
|
||||
|
||||
|
||||
@@ -274,11 +274,32 @@ static const char *get_env(const char *key)
|
||||
|
||||
Pd_session_component::Pd_session_component(Rpc_entrypoint *ep, const char *args)
|
||||
:
|
||||
_pid(0), _ds_ep(ep)
|
||||
_pid(0), _uid(0), _gid(0), _ds_ep(ep)
|
||||
{
|
||||
Arg_string::find_arg(args, "label").string(_label, sizeof(_label),
|
||||
"<unlabeled>");
|
||||
|
||||
/*
|
||||
* Read Linux-specific session arguments
|
||||
*/
|
||||
Arg_string::find_arg(args, "root").string(_root, sizeof(_root), "");
|
||||
|
||||
_uid = Arg_string::find_arg(args, "uid").ulong_value(0);
|
||||
_gid = Arg_string::find_arg(args, "gid").ulong_value(0);
|
||||
|
||||
bool const is_chroot = (Genode::strcmp(_root, "") != 0);
|
||||
|
||||
/*
|
||||
* Print Linux-specific session arguments if specified
|
||||
*
|
||||
* This output used for the automated 'lx_pd_args' test.
|
||||
*/
|
||||
if (is_chroot || _uid || _gid)
|
||||
printf("PD session for '%s'\n", _label);
|
||||
|
||||
if (is_chroot) printf(" root: %s\n", _root);
|
||||
if (_uid) printf(" uid: %u\n", _uid);
|
||||
if (_gid) printf(" gid: %u\n", _gid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user