Add a seccomp filter to prevent creating setuid/setgid binaries

This prevents builders from setting the S_ISUID or S_ISGID bits,
preventing users from using a nixbld* user to create a setuid/setgid
binary to interfere with subsequent builds under the same nixbld* uid.

This is based on aszlig's seccomp code
(47f587700d).

Reported by Linus Heckemann.
This commit is contained in:
Eelco Dolstra 2017-05-29 11:34:24 +02:00
parent 6e01ecd112
commit 6cc6c15a2d
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 54 additions and 1 deletions

View file

@ -176,6 +176,13 @@ AC_SUBST(HAVE_SODIUM, [$have_sodium])
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"]) PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])
# Look for libseccomp, required for Linux sandboxing.
if test "$sys_name" = linux; then
PKG_CHECK_MODULES([LIBSECCOMP], [libseccomp],
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
fi
# Look for aws-cpp-sdk-s3. # Look for aws-cpp-sdk-s3.
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([aws/s3/S3Client.h], AC_CHECK_HEADERS([aws/s3/S3Client.h],

View file

@ -30,6 +30,7 @@ let
docbook5 docbook5_xsl docbook5 docbook5_xsl
autoconf-archive autoconf-archive
git git
libseccomp
]; ];
configureFlags = "--enable-gc"; configureFlags = "--enable-gc";
@ -78,6 +79,7 @@ let
openssl pkgconfig sqlite boehmgc openssl pkgconfig sqlite boehmgc
] ]
++ lib.optional stdenv.isLinux libseccomp
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium ++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) ++ lib.optional (stdenv.isLinux || stdenv.isDarwin)
(aws-sdk-cpp.override { (aws-sdk-cpp.override {

View file

@ -22,7 +22,8 @@ with import ./release-common.nix { inherit pkgs; };
# For nix-perl # For nix-perl
perl perl
perlPackages.DBDSQLite perlPackages.DBDSQLite
]; ]
++ lib.optional stdenv.isLinux libseccomp;
inherit configureFlags; inherit configureFlags;

View file

@ -46,6 +46,7 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <seccomp.h>
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old)) #define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
#endif #endif
@ -2298,6 +2299,42 @@ void DerivationGoal::doExportReferencesGraph()
} }
void setupSeccomp()
{
#if __linux__
scmp_filter_ctx ctx;
if (!(ctx = seccomp_init(SCMP_ACT_ALLOW)))
throw SysError("unable to initialize seccomp mode 2");
Finally cleanup([&]() {
seccomp_release(ctx);
});
if (seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0)
throw SysError("unable to add 32-bit seccomp architecture");
for (int perm : { S_ISUID, S_ISGID }) {
// TODO: test chmod and fchmod.
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1,
SCMP_A1(SCMP_CMP_MASKED_EQ, perm, 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, perm, 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, perm, perm)) != 0)
throw SysError("unable to add seccomp rule");
}
if (seccomp_load(ctx) != 0)
throw SysError("unable to load seccomp BPF program");
#endif
}
void DerivationGoal::runChild() void DerivationGoal::runChild()
{ {
/* Warning: in the child we should absolutely not make any SQLite /* Warning: in the child we should absolutely not make any SQLite
@ -2307,6 +2344,8 @@ void DerivationGoal::runChild()
commonChildInit(builderOut); commonChildInit(builderOut);
setupSeccomp();
bool setUser = true; bool setUser = true;
/* Make the contents of netrc available to builtin:fetchurl /* Make the contents of netrc available to builtin:fetchurl

View file

@ -18,6 +18,10 @@ ifeq ($(OS), SunOS)
libstore_LDFLAGS += -lsocket libstore_LDFLAGS += -lsocket
endif endif
ifeq ($(OS), Linux)
libstore_LDFLAGS += -lseccomp
endif
libstore_CXXFLAGS = \ libstore_CXXFLAGS = \
-DNIX_PREFIX=\"$(prefix)\" \ -DNIX_PREFIX=\"$(prefix)\" \
-DNIX_STORE_DIR=\"$(storedir)\" \ -DNIX_STORE_DIR=\"$(storedir)\" \