diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2017-05-29 11:34:24 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2017-05-29 16:14:10 +0200 |
commit | 6cc6c15a2d50d0021d7242e9806ed6d54538de17 (patch) | |
tree | e9a5fbd03cd6c1e0a1d8b68fff784f2d0f29dee7 /src/libstore/build.cc | |
parent | 6e01ecd112dce8d8bbe46c839f982892a3ffb589 (diff) |
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
(47f587700d646f5b03a42f2fa57c28875a31efbe).
Reported by Linus Heckemann.
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r-- | src/libstore/build.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 44cae3431..06d259606 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -46,6 +46,7 @@ #include <sys/param.h> #include <sys/mount.h> #include <sys/syscall.h> +#include <seccomp.h> #define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old)) #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() { /* Warning: in the child we should absolutely not make any SQLite @@ -2307,6 +2344,8 @@ void DerivationGoal::runChild() commonChildInit(builderOut); + setupSeccomp(); + bool setUser = true; /* Make the contents of netrc available to builtin:fetchurl |