Files
genode/base-linux/src/base/process/process.cc
Norman Feske b45242c50f Add chroot support to core
Since the recent move of the process creation into core, the original chroot trampoline
mechanism implemented in 'os/src/app/chroot' does not work anymore. A
process could simply escape the chroot environment by spawning a new
process via core's PD service. Therefore, this patch moves the chroot
support into core. So the chroot policy becomes mandatory part of the
process creation.  For each process created by core, core checks for
'root' argument of the PD session. If a path is present, core takes the
precautions needed to execute the new process in the specified chroot
environment.

This conceptual change implies minor changes with respect to the Genode
API and the configuration of the init process. The API changes are the
enhancement of the 'Genode::Child' and 'Genode::Process' constructors to
take the root path as argument. Init supports the specification of a
chroot per process by specifying the new 'root' attribute to the
'<start>' node of the process. In line with these changes, the
'Loader::Session::start' function has been enhanced with the additional
(optional) root argument.
2012-11-05 17:31:05 +01:00

84 lines
2.0 KiB
C++

/*
* \brief Implementation of process creation for Linux
* \author Norman Feske
* \date 2006-07-06
*/
/*
* Copyright (C) 2006-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.
*/
/* Genode includes */
#include <base/elf.h>
#include <base/env.h>
#include <base/process.h>
#include <base/printf.h>
#include <linux_pd_session/client.h>
/* framework-internal includes */
#include <linux_syscalls.h>
using namespace Genode;
Dataspace_capability Process::_dynamic_linker_cap;
/**
* Check for dynamic ELF header
*/
static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
{
/* attach ELF locally */
addr_t elf_addr;
try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
catch (...) { return false; }
/*
* If attach is called within core, it will return zero because
* Linux uses Core_rm_session.
*/
if (!elf_addr) return false;
/* read program header and interpreter */
Elf_binary elf((addr_t)elf_addr);
env()->rm_session()->detach((void *)elf_addr);
return elf.is_dynamically_linked();
}
Process::Process(Dataspace_capability elf_data_ds_cap,
Ram_session_capability ram_session_cap,
Cpu_session_capability cpu_session_cap,
Rm_session_capability rm_session_cap,
Parent_capability parent_cap,
char const *name,
char const *root)
:
_pd(name, root),
_cpu_session_client(Cpu_session_capability()),
_rm_session_client(Rm_session_capability())
{
/* check for dynamic program header */
if (_check_dynamic_elf(elf_data_ds_cap)) {
if (!_dynamic_linker_cap.valid()) {
PERR("Dynamically linked file found, but no dynamic linker binary present");
return;
}
elf_data_ds_cap = _dynamic_linker_cap;
}
Linux_pd_session_client lx_pd(static_cap_cast<Linux_pd_session>(_pd.cap()));
lx_pd.assign_parent(parent_cap);
lx_pd.start(elf_data_ds_cap);
}
Process::~Process() { }