mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
Move seccomp code
This commit is contained in:
parent
b623fe8d14
commit
9e2151d839
2 changed files with 117 additions and 116 deletions
|
@ -33,11 +33,6 @@
|
|||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include "linux/fchmodat2-compat.hh"
|
||||
# include <sys/syscall.h>
|
||||
# if HAVE_SECCOMP
|
||||
# include <seccomp.h>
|
||||
# endif
|
||||
# include "nix/util/cgroup.hh"
|
||||
#endif
|
||||
|
||||
|
@ -1337,95 +1332,6 @@ void DerivationBuilderImpl::chownToBuilder(const Path & path)
|
|||
throw SysError("cannot change ownership of '%1%'", path);
|
||||
}
|
||||
|
||||
|
||||
void setupSeccomp()
|
||||
{
|
||||
#ifdef __linux__
|
||||
if (!settings.filterSyscalls) return;
|
||||
#if HAVE_SECCOMP
|
||||
scmp_filter_ctx ctx;
|
||||
|
||||
if (!(ctx = seccomp_init(SCMP_ACT_ALLOW)))
|
||||
throw SysError("unable to initialize seccomp mode 2");
|
||||
|
||||
Finally cleanup([&]() {
|
||||
seccomp_release(ctx);
|
||||
});
|
||||
|
||||
constexpr std::string_view nativeSystem = NIX_LOCAL_SYSTEM;
|
||||
|
||||
if (nativeSystem == "x86_64-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0)
|
||||
throw SysError("unable to add 32-bit seccomp architecture");
|
||||
|
||||
if (nativeSystem == "x86_64-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_X32) != 0)
|
||||
throw SysError("unable to add X32 seccomp architecture");
|
||||
|
||||
if (nativeSystem == "aarch64-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_ARM) != 0)
|
||||
printError("unable to add ARM seccomp architecture; this may result in spurious build failures if running 32-bit ARM processes");
|
||||
|
||||
if (nativeSystem == "mips64-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_MIPS) != 0)
|
||||
printError("unable to add mips seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_MIPS64N32) != 0)
|
||||
printError("unable to add mips64-*abin32 seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64el-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL) != 0)
|
||||
printError("unable to add mipsel seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64el-linux" &&
|
||||
seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32) != 0)
|
||||
printError("unable to add mips64el-*abin32 seccomp architecture");
|
||||
|
||||
/* Prevent builders from creating setuid/setgid binaries. */
|
||||
for (int perm : { S_ISUID, S_ISGID }) {
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), NIX_SYSCALL_FCHMODAT2, 1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
}
|
||||
|
||||
/* Prevent builders from using EAs or ACLs. Not all filesystems
|
||||
support these, and they're not allowed in the Nix store because
|
||||
they're not representable in the NAR serialisation. */
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(getxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lgetxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fgetxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(setxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lsetxattr), 0) != 0 ||
|
||||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, settings.allowNewPrivileges ? 0 : 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
|
||||
throw Error(
|
||||
"seccomp is not supported on this platform; "
|
||||
"you can bypass this error by setting the option 'filter-syscalls' to false, but note that untrusted builds can then create setuid binaries!");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void DerivationBuilderImpl::runChild()
|
||||
{
|
||||
/* Warning: in the child we should absolutely not make any SQLite
|
||||
|
@ -1437,12 +1343,6 @@ void DerivationBuilderImpl::runChild()
|
|||
|
||||
commonChildInit();
|
||||
|
||||
try {
|
||||
setupSeccomp();
|
||||
} catch (...) {
|
||||
if (buildUser) throw;
|
||||
}
|
||||
|
||||
/* Make the contents of netrc and the CA certificate bundle
|
||||
available to builtin:fetchurl (which may run under a
|
||||
different uid and/or in a sandbox). */
|
||||
|
|
|
@ -1,25 +1,123 @@
|
|||
#ifdef __linux__
|
||||
|
||||
# ifdef __linux__
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
# include <netinet/ip.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sched.h>
|
||||
# include <sys/param.h>
|
||||
# include <sys/mount.h>
|
||||
# include <sys/syscall.h>
|
||||
# include "nix/util/namespaces.hh"
|
||||
# if HAVE_SECCOMP
|
||||
# include <seccomp.h>
|
||||
# endif
|
||||
# define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
|
||||
# include "nix/util/cgroup.hh"
|
||||
# include "nix/store/personality.hh"
|
||||
# include "linux/fchmodat2-compat.hh"
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
# include <netinet/ip.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sched.h>
|
||||
# include <sys/param.h>
|
||||
# include <sys/mount.h>
|
||||
# include <sys/syscall.h>
|
||||
# include "nix/util/namespaces.hh"
|
||||
# if HAVE_SECCOMP
|
||||
# include <seccomp.h>
|
||||
# endif
|
||||
# define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
|
||||
# include "nix/util/cgroup.hh"
|
||||
# include "nix/store/personality.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
static void setupSeccomp()
|
||||
{
|
||||
if (!settings.filterSyscalls)
|
||||
return;
|
||||
|
||||
# if HAVE_SECCOMP
|
||||
scmp_filter_ctx ctx;
|
||||
|
||||
if (!(ctx = seccomp_init(SCMP_ACT_ALLOW)))
|
||||
throw SysError("unable to initialize seccomp mode 2");
|
||||
|
||||
Finally cleanup([&]() { seccomp_release(ctx); });
|
||||
|
||||
constexpr std::string_view nativeSystem = NIX_LOCAL_SYSTEM;
|
||||
|
||||
if (nativeSystem == "x86_64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0)
|
||||
throw SysError("unable to add 32-bit seccomp architecture");
|
||||
|
||||
if (nativeSystem == "x86_64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_X32) != 0)
|
||||
throw SysError("unable to add X32 seccomp architecture");
|
||||
|
||||
if (nativeSystem == "aarch64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_ARM) != 0)
|
||||
printError(
|
||||
"unable to add ARM seccomp architecture; this may result in spurious build failures if running 32-bit ARM processes");
|
||||
|
||||
if (nativeSystem == "mips64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_MIPS) != 0)
|
||||
printError("unable to add mips seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_MIPS64N32) != 0)
|
||||
printError("unable to add mips64-*abin32 seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64el-linux" && seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL) != 0)
|
||||
printError("unable to add mipsel seccomp architecture");
|
||||
|
||||
if (nativeSystem == "mips64el-linux" && seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32) != 0)
|
||||
printError("unable to add mips64el-*abin32 seccomp architecture");
|
||||
|
||||
/* Prevent builders from creating setuid/setgid binaries. */
|
||||
for (int perm : {S_ISUID, S_ISGID}) {
|
||||
if (seccomp_rule_add(
|
||||
ctx,
|
||||
SCMP_ACT_ERRNO(EPERM),
|
||||
SCMP_SYS(chmod),
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm))
|
||||
!= 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(
|
||||
ctx,
|
||||
SCMP_ACT_ERRNO(EPERM),
|
||||
SCMP_SYS(fchmod),
|
||||
1,
|
||||
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm))
|
||||
!= 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(
|
||||
ctx,
|
||||
SCMP_ACT_ERRNO(EPERM),
|
||||
SCMP_SYS(fchmodat),
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm))
|
||||
!= 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_rule_add(
|
||||
ctx,
|
||||
SCMP_ACT_ERRNO(EPERM),
|
||||
NIX_SYSCALL_FCHMODAT2,
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm))
|
||||
!= 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
}
|
||||
|
||||
/* Prevent builders from using EAs or ACLs. Not all filesystems
|
||||
support these, and they're not allowed in the Nix store because
|
||||
they're not representable in the NAR serialisation. */
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(getxattr), 0) != 0
|
||||
|| seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lgetxattr), 0) != 0
|
||||
|| seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fgetxattr), 0) != 0
|
||||
|| seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(setxattr), 0) != 0
|
||||
|| seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lsetxattr), 0) != 0
|
||||
|| seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
|
||||
throw SysError("unable to add seccomp rule");
|
||||
|
||||
if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, settings.allowNewPrivileges ? 0 : 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
|
||||
throw Error(
|
||||
"seccomp is not supported on this platform; "
|
||||
"you can bypass this error by setting the option 'filter-syscalls' to false, but note that untrusted builds can then create setuid binaries!");
|
||||
# endif
|
||||
}
|
||||
|
||||
static void doBind(const Path & source, const Path & target, bool optional = false)
|
||||
{
|
||||
debug("bind mounting '%1%' to '%2%'", source, target);
|
||||
|
@ -608,6 +706,9 @@ struct LinuxDerivationBuilder : DerivationBuilderImpl
|
|||
if (rmdir("real-root") == -1)
|
||||
throw SysError("cannot remove real-root directory");
|
||||
|
||||
// FIXME: move to LinuxDerivationBuilder
|
||||
setupSeccomp();
|
||||
|
||||
// FIXME: move to LinuxDerivationBuilder
|
||||
linux::setPersonality(drv.platform);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue