forked from lix-project/lix
libstore/linux: compile the seccomp BPF explicitly
This is a preparation for precompiling the filter, which is done separately.
The behaviour should be unchanged for now.
Change-Id: I899aa7242962615949208597aca88913feba1cb8
This commit is contained in:
parent
741d3b441c
commit
403fa9e2b6
|
@ -11,6 +11,7 @@
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
|
|
||||||
#if HAVE_SECCOMP
|
#if HAVE_SECCOMP
|
||||||
|
#include <linux/filter.h>
|
||||||
#include <seccomp.h>
|
#include <seccomp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -146,11 +147,8 @@ static void allowSyscall(scmp_filter_ctx ctx, int syscall) {
|
||||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), syscall, 1, SCMP_A##modePos(SCMP_CMP_MASKED_EQ, S_ISGID, S_ISGID)) != 0) \
|
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), syscall, 1, SCMP_A##modePos(SCMP_CMP_MASKED_EQ, S_ISGID, S_ISGID)) != 0) \
|
||||||
throw SysError("unable to add seccomp rule");
|
throw SysError("unable to add seccomp rule");
|
||||||
|
|
||||||
#endif
|
static std::vector<struct sock_filter> compileSyscallFilter()
|
||||||
|
|
||||||
void LinuxLocalDerivationGoal::setupSyscallFilter()
|
|
||||||
{
|
{
|
||||||
#if HAVE_SECCOMP
|
|
||||||
scmp_filter_ctx ctx;
|
scmp_filter_ctx ctx;
|
||||||
|
|
||||||
// Pretend that syscalls we don't yet know about don't exist.
|
// Pretend that syscalls we don't yet know about don't exist.
|
||||||
|
@ -703,18 +701,40 @@ void LinuxLocalDerivationGoal::setupSyscallFilter()
|
||||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
||||||
throw SysError("unable to add seccomp rule");
|
throw SysError("unable to add seccomp rule");
|
||||||
|
|
||||||
|
Pipe filterPipe;
|
||||||
|
filterPipe.create();
|
||||||
|
auto filterBytes_ = std::async([&]() {
|
||||||
|
return drainFD(filterPipe.readSide.get());
|
||||||
|
});
|
||||||
|
if (seccomp_export_bpf(ctx, filterPipe.writeSide.get()) != 0)
|
||||||
|
throw SysError("unable to compile seccomp BPF program");
|
||||||
|
filterPipe.writeSide.close();
|
||||||
|
auto filterBytes = filterBytes_.get();
|
||||||
|
|
||||||
|
assert(filterBytes.size() % sizeof(struct sock_filter) == 0);
|
||||||
|
std::vector<struct sock_filter> filter(filterBytes.size() / sizeof(struct sock_filter));
|
||||||
|
std::memcpy(filter.data(), filterBytes.data(), filterBytes.size());
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void LinuxLocalDerivationGoal::setupSyscallFilter()
|
||||||
|
{
|
||||||
// Set the NO_NEW_PRIVS prctl flag.
|
// Set the NO_NEW_PRIVS prctl flag.
|
||||||
// This both makes loading seccomp filters work for unprivileged users,
|
// This both makes loading seccomp filters work for unprivileged users,
|
||||||
// and is an additional security measure in its own right.
|
// and is an additional security measure in its own right.
|
||||||
if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 1) != 0)
|
|
||||||
throw SysError("unable to set 'no new privileges' seccomp attribute");
|
|
||||||
|
|
||||||
if (seccomp_load(ctx) != 0)
|
|
||||||
throw SysError("unable to load seccomp BPF program");
|
|
||||||
#else
|
|
||||||
// Still set the no-new-privileges flag if libseccomp is not available.
|
|
||||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
|
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
|
||||||
throw SysError("PR_SET_NO_NEW_PRIVS failed");
|
throw SysError("PR_SET_NO_NEW_PRIVS failed");
|
||||||
|
#if HAVE_SECCOMP
|
||||||
|
auto seccompBPF = compileSyscallFilter();
|
||||||
|
assert(seccompBPF.size() <= std::numeric_limits<unsigned short>::max());
|
||||||
|
struct sock_fprog fprog = {
|
||||||
|
.len = static_cast<unsigned short>(seccompBPF.size()),
|
||||||
|
.filter = seccompBPF.data(),
|
||||||
|
};
|
||||||
|
if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &fprog) != 0)
|
||||||
|
throw SysError("unable to load seccomp BPF program");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue