mirror of
https://github.com/LibreOffice/online.git
synced 2025-08-20 23:24:34 +00:00
Initial seccomp work.
Add a list of unhelpful looking system calls to improve containment. Change-Id: I2e4bf3e0a6a752d427299728663d17120586bb10
This commit is contained in:
150
common/Seccomp.cpp
Normal file
150
common/Seccomp.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
/*
|
||||
* Code to lock-down the environment of the processes we run, to avoid
|
||||
* exotic or un-necessary system calls to be used to break containment.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <ftw.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/capability.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include <common/Log.hpp>
|
||||
|
||||
#include <Seccomp.hpp>
|
||||
|
||||
#include <sys/prctl.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/seccomp.h>
|
||||
|
||||
#if defined(__x86_64__)
|
||||
# define AUDIT_ARCH_NR AUDIT_ARCH_X86_64
|
||||
#else
|
||||
# error "Platform does not support seccomp filtering yet - unsafe."
|
||||
#endif
|
||||
|
||||
namespace Seccomp {
|
||||
|
||||
bool lockdown(Type type)
|
||||
{
|
||||
(void)type; // so far just the kit.
|
||||
|
||||
// FIXME: partition better to give log() branching.
|
||||
#define KILL_SYSCALL(name) \
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \
|
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
|
||||
|
||||
struct sock_filter filterCode[] = {
|
||||
// Check our architecture is correct.
|
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, arch)),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_NR, 1, 0),
|
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
|
||||
|
||||
// Load sycall number
|
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
|
||||
|
||||
// FIXME: white-list low-numbers / safe common-cases first
|
||||
// at the expense of some cross-platform complexity ?
|
||||
|
||||
// FIXME: should we bother blocking calls that have early
|
||||
// permission checks we don't meet ?
|
||||
|
||||
#if 0
|
||||
// cf. eg. /usr/include/asm/unistd_64.h ...
|
||||
KILL_SYSCALL(ioctl),
|
||||
KILL_SYSCALL(mincore),
|
||||
KILL_SYSCALL(shmget),
|
||||
KILL_SYSCALL(shmat),
|
||||
KILL_SYSCALL(shmctl),
|
||||
#endif
|
||||
KILL_SYSCALL(getitimer),
|
||||
KILL_SYSCALL(setitimer),
|
||||
KILL_SYSCALL(sendfile),
|
||||
KILL_SYSCALL(shutdown),
|
||||
KILL_SYSCALL(listen),
|
||||
#if 0
|
||||
KILL_SYSCALL(wait4),
|
||||
#endif
|
||||
KILL_SYSCALL(kill), // !
|
||||
KILL_SYSCALL(shmctl),
|
||||
KILL_SYSCALL(ptrace), // !
|
||||
KILL_SYSCALL(capset),
|
||||
#if 0
|
||||
KILL_SYSCALL(uselib),
|
||||
#endif
|
||||
KILL_SYSCALL(personality), // !
|
||||
KILL_SYSCALL(vhangup),
|
||||
KILL_SYSCALL(modify_ldt), // !
|
||||
KILL_SYSCALL(pivot_root), // !
|
||||
KILL_SYSCALL(chroot),
|
||||
KILL_SYSCALL(acct), // !
|
||||
KILL_SYSCALL(sync), // I/O perf.
|
||||
KILL_SYSCALL(mount),
|
||||
KILL_SYSCALL(umount2),
|
||||
KILL_SYSCALL(swapon),
|
||||
KILL_SYSCALL(swapoff),
|
||||
KILL_SYSCALL(reboot), // !
|
||||
KILL_SYSCALL(sethostname),
|
||||
KILL_SYSCALL(setdomainname),
|
||||
KILL_SYSCALL(tkill),
|
||||
KILL_SYSCALL(mbind), // vm bits
|
||||
KILL_SYSCALL(set_mempolicy), // vm bits
|
||||
KILL_SYSCALL(get_mempolicy), // vm bits
|
||||
KILL_SYSCALL(kexec_load),
|
||||
KILL_SYSCALL(add_key), // kernel keyring
|
||||
KILL_SYSCALL(request_key), // kernel keyring
|
||||
KILL_SYSCALL(keyctl), // kernel keyring
|
||||
KILL_SYSCALL(inotify_init),
|
||||
KILL_SYSCALL(inotify_add_watch),
|
||||
KILL_SYSCALL(inotify_rm_watch),
|
||||
KILL_SYSCALL(unshare),
|
||||
KILL_SYSCALL(splice),
|
||||
KILL_SYSCALL(tee),
|
||||
KILL_SYSCALL(vmsplice), // vm bits
|
||||
KILL_SYSCALL(move_pages), // vm bits
|
||||
KILL_SYSCALL(inotify_init1),
|
||||
KILL_SYSCALL(fanotify_init),
|
||||
KILL_SYSCALL(fanotify_mark),
|
||||
KILL_SYSCALL(seccomp), // no further fiddling
|
||||
KILL_SYSCALL(bpf), // no further fiddling
|
||||
|
||||
// allow the rest - FIXME: prolly we should white-list
|
||||
// but LibreOffice is rather large.
|
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
|
||||
};
|
||||
|
||||
struct sock_fprog filter = {
|
||||
sizeof(filterCode)/sizeof(filterCode[0]), // length
|
||||
filterCode
|
||||
};
|
||||
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
|
||||
{
|
||||
LOG_ERR("Cannot turn off acquisition of new privileges for us & children");
|
||||
return false;
|
||||
}
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &filter))
|
||||
{
|
||||
LOG_ERR("Failed to install seccomp syscall filter");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_TRC("Install seccomp filter successfully.");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Seccomp
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Reference in New Issue
Block a user