mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
base-linux: Support customization of UIDs and GIDs
With this patch, custom UIDs and GIDs can be assigned to individual Genode processes or whole Genode subsystems. The new 'base-linux/run/lx_uid.run' script contains an example of how to use the feature. Fixes #510
This commit is contained in:
parent
959df5d46b
commit
8e831d2224
101
base-linux/run/lx_uid.run
Normal file
101
base-linux/run/lx_uid.run
Normal file
@ -0,0 +1,101 @@
|
||||
#
|
||||
# \brief Test for assigning custom UIDs and GIDs to Genode processes
|
||||
# \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_55_66" uid="55" gid="66">
|
||||
<binary name="init" />
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config/>
|
||||
</start>
|
||||
|
||||
<!-- we expect the GID of init_77 to equal the UID -->
|
||||
<start name="init_77" uid="77">
|
||||
<binary name="init" />
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="CAP"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service><parent/></any-service>
|
||||
</default-route>
|
||||
|
||||
<!-- we expect the GID and UID of init_sub_77 to inherit
|
||||
its UID and GIDs from its parent policy. -->
|
||||
<start name="init_sub_77">
|
||||
<binary name="init" />
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
#
|
||||
# Copy boot modules into run directory
|
||||
#
|
||||
# We cannot use the predefined 'build_boot_image' function here because
|
||||
# this would create mere symlinks. However, we need to enable the setuid
|
||||
# and setgid capabilities for core, which won't work if core were a symlink.
|
||||
#
|
||||
foreach binary { core init } {
|
||||
exec cp -H bin/$binary [run_dir] }
|
||||
|
||||
#
|
||||
# Allow core to set arbitrary UIDs and GIDs
|
||||
#
|
||||
exec sudo setcap cap_setuid,cap_setgid=ep [run_dir]/core
|
||||
|
||||
#
|
||||
# Execute Genode until the point where init_sub_77 is up
|
||||
#
|
||||
run_genode_until {\[init -> init_77 -> init_sub_77\].*No children to start.*\n} 10
|
||||
|
||||
#
|
||||
# Obtain the list of Genode user processes starting with the name 'init'
|
||||
#
|
||||
set ps_output [exec ps -eo uid,gid,cmd | grep Genode | grep init]
|
||||
|
||||
puts "Genode user processes:\n$ps_output"
|
||||
|
||||
#
|
||||
# Validate output of ps
|
||||
#
|
||||
# We are only interested in the lines for the init instances with the
|
||||
# customized UIDs and GIDs.
|
||||
#
|
||||
if {![regexp {55\s*66 \[Genode\] init_55_66} $ps_output]
|
||||
|| ![regexp {77\s*77 \[Genode\] init_77} $ps_output]
|
||||
|| ![regexp {77\s*77 \[Genode\] init_77 -> init_sub_77} $ps_output]} {
|
||||
puts stderr "Unexpected output of ps"
|
||||
exit 1
|
||||
}
|
||||
|
||||
puts "Test succeeded"
|
||||
|
@ -72,11 +72,6 @@ inline int lx_execve(const char *filename, char *const argv[],
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send signal to process
|
||||
*
|
||||
* This function is used by core to kill processes.
|
||||
*/
|
||||
inline int lx_kill(int pid, int signal)
|
||||
{
|
||||
return lx_syscall(SYS_kill, pid, signal);
|
||||
@ -90,6 +85,18 @@ inline int lx_create_process(int (*entry)(void *), void *stack, void *arg)
|
||||
}
|
||||
|
||||
|
||||
inline int lx_setuid(unsigned int uid)
|
||||
{
|
||||
return lx_syscall(SYS_setuid, uid);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_setgid(unsigned int gid)
|
||||
{
|
||||
return lx_syscall(SYS_setgid, gid);
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Chroot handling **
|
||||
*********************/
|
||||
|
@ -195,11 +195,25 @@ static bool setup_chroot_environment(char const *chroot_path)
|
||||
*/
|
||||
struct Execve_args
|
||||
{
|
||||
char const *filename;
|
||||
char const *root;
|
||||
char *const *argv;
|
||||
char *const *envp;
|
||||
int parent_sd;
|
||||
char const *filename;
|
||||
char const *root;
|
||||
char * const *argv;
|
||||
char * const *envp;
|
||||
unsigned int const uid;
|
||||
unsigned int const gid;
|
||||
int const parent_sd;
|
||||
|
||||
Execve_args(char const *filename,
|
||||
char const *root,
|
||||
char * const *argv,
|
||||
char * const *envp,
|
||||
unsigned int uid,
|
||||
unsigned int gid,
|
||||
int parent_sd)
|
||||
:
|
||||
filename(filename), root(root), argv(argv), envp(envp),
|
||||
uid(uid), gid(gid), parent_sd(parent_sd)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@ -242,6 +256,25 @@ static int _exec_child(Execve_args *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set UID and GID
|
||||
*
|
||||
* We must set the GID prior setting the UID because setting the GID won't
|
||||
* be possible anymore once we set the UID to non-root.
|
||||
*/
|
||||
if (arg->gid) {
|
||||
int const ret = lx_setgid(arg->gid);
|
||||
if (ret)
|
||||
PWRN("Could not set PID %d (%s) to GID %u (error %d)",
|
||||
lx_getpid(), arg->filename, arg->gid, ret);
|
||||
}
|
||||
if (arg->uid) {
|
||||
int const ret = lx_setuid(arg->uid);
|
||||
if (ret)
|
||||
PWRN("Could not set PID %d (%s) to UID %u (error %d)",
|
||||
lx_getpid(), arg->filename, arg->uid, ret);
|
||||
}
|
||||
|
||||
return lx_execve(arg->filename, arg->argv, arg->envp);
|
||||
}
|
||||
|
||||
@ -289,6 +322,15 @@ Pd_session_component::Pd_session_component(Rpc_entrypoint *ep, const char *args)
|
||||
|
||||
bool const is_chroot = (Genode::strcmp(_root, "") != 0);
|
||||
|
||||
/*
|
||||
* If a UID is specified but no GID, we use the UID as GID. This way, a
|
||||
* configuration error where the UID is defined but the GID is left
|
||||
* undefined won't result in the execution of the new process with the
|
||||
* root user's GID.
|
||||
*/
|
||||
if (_gid == 0)
|
||||
_gid = _uid;
|
||||
|
||||
/*
|
||||
* Print Linux-specific session arguments if specified
|
||||
*
|
||||
@ -375,7 +417,8 @@ void Pd_session_component::start(Capability<Dataspace> binary)
|
||||
* Argument frame as passed to 'clone'. Because, we can only pass a single
|
||||
* pointer, all arguments are embedded within the 'execve_args' struct.
|
||||
*/
|
||||
Execve_args arg = { filename.buf, _root, argv_buf, env, _parent.dst().socket };
|
||||
Execve_args arg(filename.buf, _root, argv_buf, env, _uid, _gid,
|
||||
_parent.dst().socket);
|
||||
|
||||
_pid = lx_create_process((int (*)(void *))_exec_child,
|
||||
stack + STACK_SIZE - sizeof(umword_t), &arg);
|
||||
|
@ -1,3 +1,4 @@
|
||||
TARGET = test-chroot_loader
|
||||
SRC_CC = main.cc
|
||||
LIBS += cxx env
|
||||
TARGET = test-chroot_loader
|
||||
REQUIRES += linux
|
||||
SRC_CC = main.cc
|
||||
LIBS += cxx env
|
||||
|
Loading…
Reference in New Issue
Block a user