genode/repos/base-linux/src/include/base/internal/native_thread.h

114 lines
2.3 KiB
C
Raw Normal View History

/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#include <base/stdint.h>
base-linux: socket descriptor caps for RPC On Linux, Genode used to represent each RPC object by a socket descriptor of the receiving thread (entrypoint) and a globally-unique value that identifies the object. Because the latter was transferred as plain message payload, clients had to be trusted to not forge the values. For this reason, Linux could not be considered as a productive Genode base platform but remained merely a development vehicle. This patch changes the RPC mechanism such that each RPC object is represented by a dedicated socket pair. Entrypoints wait on a set of the local ends of the socket pairs of all RPC objects managed by the respective entrypoint. The epoll kernel interface is used as the underlying mechanism to wait for a set of socket descriptors at the server side. When delegating a capability, the remote end of the socket pair is transferred to the recipient along with a plaintext copy of the socket-descriptor value of the local end. The latter value serves as a hint for re-identifiying a capability whenever it is delegated back to its origin. Note that the client is not trusted to preserve this information. The integrity of the hint value is protected by comparing the inode values of incoming and already present capablities at the originating site (whenever the capability is invoked or presented to the owner of the RPC object). The new mechanism effectively equips base-linux with Genode's capablity model as described in the Chapter 3 of the Genode Foundations book. That said, the sandboxing of components cannot be assumed at this point because each component has still direct access to the Linux system-call interface. This patch is based on the extensive exploration work conducted by Stefan Thoeni who strongly motivated the inclusion of this feature into Genode. Issue #3581
2020-04-09 12:30:21 +02:00
#include <base/native_capability.h>
#include <linux_syscalls.h>
namespace Genode { struct Native_thread; }
base-linux: socket descriptor caps for RPC On Linux, Genode used to represent each RPC object by a socket descriptor of the receiving thread (entrypoint) and a globally-unique value that identifies the object. Because the latter was transferred as plain message payload, clients had to be trusted to not forge the values. For this reason, Linux could not be considered as a productive Genode base platform but remained merely a development vehicle. This patch changes the RPC mechanism such that each RPC object is represented by a dedicated socket pair. Entrypoints wait on a set of the local ends of the socket pairs of all RPC objects managed by the respective entrypoint. The epoll kernel interface is used as the underlying mechanism to wait for a set of socket descriptors at the server side. When delegating a capability, the remote end of the socket pair is transferred to the recipient along with a plaintext copy of the socket-descriptor value of the local end. The latter value serves as a hint for re-identifiying a capability whenever it is delegated back to its origin. Note that the client is not trusted to preserve this information. The integrity of the hint value is protected by comparing the inode values of incoming and already present capablities at the originating site (whenever the capability is invoked or presented to the owner of the RPC object). The new mechanism effectively equips base-linux with Genode's capablity model as described in the Chapter 3 of the Genode Foundations book. That said, the sandboxing of components cannot be assumed at this point because each component has still direct access to the Linux system-call interface. This patch is based on the extensive exploration work conducted by Stefan Thoeni who strongly motivated the inclusion of this feature into Genode. Issue #3581
2020-04-09 12:30:21 +02:00
class Genode::Native_thread
{
base-linux: socket descriptor caps for RPC On Linux, Genode used to represent each RPC object by a socket descriptor of the receiving thread (entrypoint) and a globally-unique value that identifies the object. Because the latter was transferred as plain message payload, clients had to be trusted to not forge the values. For this reason, Linux could not be considered as a productive Genode base platform but remained merely a development vehicle. This patch changes the RPC mechanism such that each RPC object is represented by a dedicated socket pair. Entrypoints wait on a set of the local ends of the socket pairs of all RPC objects managed by the respective entrypoint. The epoll kernel interface is used as the underlying mechanism to wait for a set of socket descriptors at the server side. When delegating a capability, the remote end of the socket pair is transferred to the recipient along with a plaintext copy of the socket-descriptor value of the local end. The latter value serves as a hint for re-identifiying a capability whenever it is delegated back to its origin. Note that the client is not trusted to preserve this information. The integrity of the hint value is protected by comparing the inode values of incoming and already present capablities at the originating site (whenever the capability is invoked or presented to the owner of the RPC object). The new mechanism effectively equips base-linux with Genode's capablity model as described in the Chapter 3 of the Genode Foundations book. That said, the sandboxing of components cannot be assumed at this point because each component has still direct access to the Linux system-call interface. This patch is based on the extensive exploration work conducted by Stefan Thoeni who strongly motivated the inclusion of this feature into Genode. Issue #3581
2020-04-09 12:30:21 +02:00
private:
/*
* Noncopyable
*/
Native_thread(Native_thread const &);
Native_thread &operator = (Native_thread const &);
public:
/*
* Unfortunately, both - PID and TID - are needed for lx_tgkill()
*/
unsigned int tid = 0; /* Native thread ID type as returned by the
'clone' system call */
unsigned int pid = 0; /* process ID (resp. thread-group ID) */
bool is_ipc_server = false;
/**
* Natively aligned memory location used in the lock implementation
*/
int futex_counter __attribute__((aligned(sizeof(Genode::addr_t)))) = 0;
struct Meta_data;
/**
* Opaque pointer to additional thread-specific meta data
*
* This pointer is used by hybrid Linux/Genode programs to maintain
* POSIX-thread-related meta data. For non-hybrid Genode programs, it
* remains unused.
*/
Meta_data *meta_data = nullptr;
class Epoll
{
private:
Lx_socketpair _control { };
Lx_epoll_sd const _epoll;
void _add (Lx_sd);
void _remove(Lx_sd);
bool _rpc_ep_exited = false;
struct Control_function : Interface
{
virtual void execute() = 0;
};
/*
* Execute functor 'fn' in the context of the 'poll' method.
*/
template <typename FN>
void _exec_control(FN const &);
public:
Epoll();
~Epoll();
/**
* Wait for incoming RPC messages
*
* \return valid socket descriptor that matches the invoked
* RPC object
*/
Lx_sd poll();
Native_capability alloc_rpc_cap();
void free_rpc_cap(Native_capability);
/**
* Flag RPC entrypoint as no longer in charge of dispatching
*/
void rpc_ep_exited() { _rpc_ep_exited = true; }
} epoll { };
Native_thread() { }
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */