base-linux: enabled seccomp

base-linux uses seccomp to reduce the available system calls
to the minimum set needed to run base-linux. There are still
some syscalls that allow accessing global state which should
be further reduced.

The combination of seccomp and socket descriptor caps should
provide an intermediate level of security for base-linux
thereby enabling base-linux as a migration path from using
the Linux kernel to the use of microkernel-based Genode.

Fixes #3581
This commit is contained in:
Stefan Thöni
2019-09-17 14:40:52 +02:00
committed by Christian Helmuth
parent 128ba65109
commit 78497c03ca
17 changed files with 404 additions and 3 deletions

View File

@ -12,9 +12,51 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/log.h>
/* base-internal includes */
#include <base/internal/globals.h>
#include <linux_syscalls.h>
#include <errno.h>
#include <sys/prctl.h> /* prctl */
#include <linux/seccomp.h> /* seccomp's constants */
void Genode::binary_ready_hook_for_platform() { }
using namespace Genode;
extern char _binary_seccomp_bpf_policy_bin_start[];
extern char _binary_seccomp_bpf_policy_bin_end[];
struct bpf_program {
Genode::uint16_t blk_cnt;
Genode::uint64_t* blks;
};
void Genode::binary_ready_hook_for_platform()
{
if (lx_prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
error("PR_SET_NO_NEW_PRIVS failed");
throw Exception();
}
for (char* i = _binary_seccomp_bpf_policy_bin_start;
i < _binary_seccomp_bpf_policy_bin_end - sizeof(Genode::uint32_t); i++) {
Genode::uint32_t* v = reinterpret_cast<Genode::uint32_t*>(i);
if (*v == 0xCAFEAFFE) {
*v = lx_getpid();
}
}
bpf_program program;
program.blk_cnt = (_binary_seccomp_bpf_policy_bin_end -
_binary_seccomp_bpf_policy_bin_start) /
sizeof(Genode::uint64_t);
program.blks = (Genode::uint64_t*)_binary_seccomp_bpf_policy_bin_start;
Genode::uint64_t flags = SECCOMP_FILTER_FLAG_TSYNC;
auto ret = lx_seccomp(SECCOMP_SET_MODE_FILTER, flags, &program);
if (ret != 0) {
error("SECCOMP_SET_MODE_FILTER failed ", ret);
throw Exception();
}
}

View File

@ -123,7 +123,10 @@ void Thread::_deinit_platform_thread()
for (;;) {
/* destroy thread locally */
int ret = lx_tgkill(native_thread().pid, native_thread().tid, LX_SIGCANCEL);
int pid = native_thread().pid;
if (pid == 0) break;
int ret = lx_tgkill(pid, native_thread().tid, LX_SIGCANCEL);
if (ret < 0) break;