genode/base-linux/src/core/platform.cc
Norman Feske 91e6ab2baf Linux: Robustness of socket life-time management
This patch improves the life-time management of socket descriptors and
addresses several corner cases exposed by the 'bomb' test.

The lookup and association of file descriptors with global IDs have been
turned into an atomic operation. Otherwise, multiple threads interacting
with the singleton 'ep_sd_registry' may override each other's
associations.

Closing the socket pair used for the reply channel has been implemented
via the RAII pattern to capture all corner cases, in particular
exceptions.

If blocking operations are interrupted by signals, we throw a
'Blocking_canceled' exception.

We preserve core's socket descriptor at 'PARENT_SOCKET_HANDLE' to avoid
a corner case where the parent capability is going to dup2'ed to the
same handle.

Support for 'Thread_base::join' within core to enable leaving Genode via
Control-C.
2012-11-26 20:58:09 +01:00

98 lines
2.1 KiB
C++

/*
* \brief Linux platform interface implementation
* \author Norman Feske
* \date 2006-06-13
*/
/*
* 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/lock.h>
/* local includes */
#include "platform.h"
#include "core_env.h"
#include "server_socket_pair.h"
/* Linux includes */
#include <core_linux_syscalls.h>
using namespace Genode;
static char _some_mem[80*1024*1024];
static Lock _wait_for_exit_lock(Lock::LOCKED); /* exit() sync */
static void signal_handler(int signum)
{
_wait_for_exit_lock.unlock();
}
Platform::Platform()
: _ram_alloc(0)
{
/* catch control-c */
lx_sigaction(2, signal_handler);
/* create resource directory under /tmp */
lx_mkdir(resource_path(), S_IRWXU);
_ram_alloc.add_range((addr_t)_some_mem, sizeof(_some_mem));
/*
* Occupy the socket handle that will be used to propagate the parent
* capability new processes. Otherwise, there may be the chance that the
* parent capability as supplied by the process creator will be assigned to
* this handle, which would result in a 'dup2' syscall taking
* PARENT_SOCKET_HANDLE as both source and target descriptor.
*/
lx_dup2(0, PARENT_SOCKET_HANDLE);
}
void Platform::wait_for_exit()
{
/* block until exit condition is satisfied */
try { _wait_for_exit_lock.lock(); }
catch (Blocking_canceled) { };
}
void Core_parent::exit(int exit_value)
{
lx_exit_group(exit_value);
}
/*****************************
** Support for IPC library **
*****************************/
namespace Genode {
Native_connection_state server_socket_pair()
{
return create_server_socket_pair(Thread_base::myself()->tid().tid);
}
void destroy_server_socket_pair(Native_connection_state const &ncs)
{
/*
* As entrypoints in core are never destructed, this function is only
* called on IPC-client destruction. In this case, it's a no-op in core
* as well as in Genode processes.
*/
if (ncs.server_sd != -1 || ncs.client_sd != -1)
PERR("%s called for IPC server which should never happen", __func__);
}
}