genode/base-linux/src/core/pd_session_component.cc

350 lines
8.2 KiB
C++
Raw Normal View History

Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
/*
2011-12-22 16:19:25 +01:00
* \brief Core implementation of the PD session interface
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
* \author Norman Feske
* \date 2012-08-15
2011-12-22 16:19:25 +01:00
*/
/*
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
* Copyright (C) 2012 Genode Labs GmbH
2011-12-22 16:19:25 +01:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
/* Genode includes */
#include <util/arg_string.h>
2011-12-22 16:19:25 +01:00
#include <base/printf.h>
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
#include <base/snprintf.h>
2011-12-22 16:19:25 +01:00
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
/* core-local includes */
2011-12-22 16:19:25 +01:00
#include <pd_session_component.h>
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
#include <dataspace_component.h>
2011-12-22 16:19:25 +01:00
/* Linux includes */
#include <core_linux_syscalls.h>
2011-12-22 16:19:25 +01:00
using namespace Genode;
/***********************************
** Utilities for chroot handling **
***********************************/
enum { MAX_PATH_LEN = 256 };
/**
* Return true if specified path is an existing directory
*/
static bool is_directory(char const *path)
{
struct stat64 s;
if (lx_stat(path, &s) != 0)
return false;
if (!(s.st_mode & S_IFDIR))
return false;
return true;
}
static bool is_path_delimiter(char c) { return c == '/'; }
static bool has_trailing_path_delimiter(char const *path)
{
char last_char = 0;
for (; *path; path++)
last_char = *path;
return is_path_delimiter(last_char);
}
/**
* Return number of path elements of given path
*/
static Genode::size_t num_path_elements(char const *path)
{
Genode::size_t count = 0;
/*
* If path starts with non-slash, the first characters belongs to a path
* element.
*/
if (*path && !is_path_delimiter(*path))
count = 1;
/* count slashes */
for (; *path; path++)
if (is_path_delimiter(*path))
count++;
return count;
}
static bool leading_path_elements(char const *path, unsigned num,
char *dst, Genode::size_t dst_len)
{
/* counter of path delimiters */
unsigned count = 0;
unsigned i = 0;
if (is_path_delimiter(path[0]))
num++;
for (; path[i] && (count < num) && (i < dst_len); i++)
{
if (is_path_delimiter(path[i]))
count++;
if (count == num)
break;
dst[i] = path[i];
}
if (i + 1 < dst_len) {
dst[i] = 0;
return true;
}
/* string is cut, append null termination anyway */
dst[dst_len - 1] = 0;
return false;
}
static void mirror_path_to_chroot(char const *chroot_path, char const *path)
{
char target_path[MAX_PATH_LEN];
Genode::snprintf(target_path, sizeof(target_path), "%s%s",
chroot_path, path);
/*
* Create directory hierarchy pointing to the target path except for the
* last element. The last element will be bind-mounted to refer to the
* original 'path'.
*/
for (unsigned i = 1; i <= num_path_elements(target_path); i++)
{
char buf[MAX_PATH_LEN];
leading_path_elements(target_path, i, buf, sizeof(buf));
/* skip existing directories */
if (is_directory(buf))
continue;
/* create new directory */
lx_mkdir(buf, 0777);
}
lx_umount(target_path);
int ret = 0;
if ((ret = lx_bindmount(path, target_path)))
PERR("bind mount failed (errno=%d)", ret);
}
/**
* Setup content of chroot environment as prerequisite to 'execve' new
* processes within the environment. I.e., the current working directory
* containing the ROM modules must be mounted at the same location within the
* chroot environment.
*/
static bool setup_chroot_environment(char const *chroot_path)
{
using namespace Genode;
static char cwd_path[MAX_PATH_LEN];
lx_getcwd(cwd_path, sizeof(cwd_path));
/*
* Validate chroot path
*/
if (!is_directory(chroot_path)) {
PERR("chroot path does not point to valid directory");
return false;
}
if (has_trailing_path_delimiter(chroot_path)) {
PERR("chroot path has trailing slash");
return false;
}
/*
* Hardlink directories needed for running Genode within the chroot
* environment.
*/
mirror_path_to_chroot(chroot_path, cwd_path);
return true;
}
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
/***************
** Utilities **
***************/
/**
* Argument frame for passing 'execve' paremeters through 'clone'
*/
struct Execve_args
{
char const *filename;
char const *root;
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
char *const *argv;
char *const *envp;
int parent_sd;
};
/**
* Startup code of the new child process
*/
static int _exec_child(Execve_args *arg)
{
lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE);
/* change to chroot environment */
if (arg->root && arg->root[0]) {
PDBG("arg->root='%s'", arg->root);
if (setup_chroot_environment(arg->root) == false) {
PERR("Could not setup chroot environment");
return -1;
}
PLOG("changing root of %s (PID %d) to %s",
arg->filename, lx_getpid(), arg->root);
int ret = lx_chroot(arg->root);
if (ret < 0) {
PERR("Syscall chroot failed (errno %d)", ret);
return -1;
}
}
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
return lx_execve(arg->filename, arg->argv, arg->envp);
}
/**
* List of Unix environment variables, initialized by the startup code
*/
extern char **lx_environ;
/**
* Read environment variable as string
*
* If no matching key exists, return an empty string.
*/
static const char *get_env(const char *key)
2011-12-22 16:19:25 +01:00
{
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
Genode::size_t key_len = Genode::strlen(key);
for (char **curr = lx_environ; curr && *curr; curr++)
if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=')
return (const char *)(*curr + key_len + 1);
return "";
2011-12-22 16:19:25 +01:00
}
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
/**************************
** PD session interface **
**************************/
Pd_session_component::Pd_session_component(Rpc_entrypoint *ep, const char *args)
:
_pid(0), _ds_ep(ep)
{
Arg_string::find_arg(args, "label").string(_label, sizeof(_label),
"<unlabeled>");
Arg_string::find_arg(args, "root").string(_root, sizeof(_root), "");
}
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
2011-12-22 16:19:25 +01:00
Pd_session_component::~Pd_session_component()
{
if (_pid)
lx_kill(_pid, 9);
}
int Pd_session_component::bind_thread(Thread_capability) { return -1; }
2011-12-22 16:19:25 +01:00
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
int Pd_session_component::assign_parent(Parent_capability parent)
2011-12-22 16:19:25 +01:00
{
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
_parent = parent;
return 0;
2011-12-22 16:19:25 +01:00
}
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
void Pd_session_component::start(Capability<Dataspace> binary)
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
{
/* lookup binary dataspace */
Dataspace_component *ds =
reinterpret_cast<Dataspace_component *>(_ds_ep->obj_by_cap(binary));
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
if (!ds) {
PERR("could not lookup binary, aborted PD startup");
return; /* XXX reflect error to client */
}
Linux_dataspace::Filename filename = ds->fname();
/* pass parent capability as environment variable to the child */
enum { ENV_STR_LEN = 256 };
static char envbuf[5][ENV_STR_LEN];
Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu",
_parent.local_name());
Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s",
get_env("DISPLAY"));
Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s",
get_env("HOME"));
Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s",
get_env("LD_LIBRARY_PATH"));
char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0],
&envbuf[3][0], &envbuf[4][0], 0 };
/* prefix name of Linux program (helps killing some zombies) */
char const *prefix = "[Genode] ";
char pname_buf[sizeof(_label) + sizeof(prefix)];
snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _label);
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
char *argv_buf[2];
argv_buf[0] = pname_buf;
argv_buf[1] = 0;
/*
* We cannot create the new process via 'fork()' because all our used
* memory including stack memory is backed by dataspaces, which had been
* mapped with the 'MAP_SHARED' flag. Therefore, after being created, the
* new process starts using the stack with the same physical memory pages
* as used by parent process. This would ultimately lead to stack
* corruption. To prevent both processes from concurrently accessing the
* same stack, we pause the execution of the parent until the child calls
* 'execve'. From then on, the child has its private memory layout. The
* desired behaviour is normally provided by 'vfork' but we use the more
* modern 'clone' call for this purpose.
*/
enum { STACK_SIZE = 4096 };
static char stack[STACK_SIZE]; /* initial stack used by the child until
calling 'execve' */
/*
* 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 };
Linux: move process creation into core Genode used to create new processes by directly forking from the respective Genode parent using the process library. The forking process created a PD session at core merely for propagating the PID of the new process into core (for later destruction). This traditional mechanisms has the following disadvantages: First, the PID reported by the creating process to core cannot easily be validated by core. Therefore core has to trust the PD client to not specify a PID of an existing process, which would happen to be killed once the PD session gets destructed. This problem is documented by issue #318. Second, there is no way for a Genode process to detect the failure of its any grandchildren. The immediate parent of a faulting process could use the SIGCHLD-and-waitpid mechanism to observe its children but this mechanism does not work transitively. By performing the process creation exclusively within core, all Genode processes become immediate child processes of core. Hence, core can respond to failures of any of those processes and reflect such conditions via core's session interfaces. Furthermore, the PID associated to a PD session is locally known within core and cannot be forged anymore. In fact, there is actually no need at all to make processes aware of any PIDs of other processes. Please note that this patch breaks the 'chroot' mechanism that comes in the form of the 'os/src/app/chroot' program. Because all processes are forked from core, a chroot'ed process could sneak outside its chroot environment by just creating a new Genode process. To address this issue, the chroot mechanism must be added to core.
2012-08-15 19:14:05 +02:00
_pid = lx_create_process((int (*)(void *))_exec_child,
stack + STACK_SIZE - sizeof(umword_t), &arg);
};