libstore/build: Forge chown() to return success
What we basically want is a seccomp mode 2 BPF program like this but for every architecture: BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_chown, 4, 0), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_fchown, 3, 0), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_fchownat, 2, 0), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_lchown, 1, 0), BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO) However, on 32 bit architectures we do have chown32, lchown32 and fchown32, so we'd need to add all the architecture blurb which libseccomp handles for us. So we only need to make sure that we add the 32bit seccomp arch while we're on x86_64 and otherwise we just stay at the native architecture which was set during seccomp_init(), which more or less replicates setting 32bit personality during runChild(). The FORCE_SUCCESS() macro here could be a bit less ugly but I think repeating the seccomp_rule_add() all over the place is way uglier. Another way would have been to create a vector of syscalls to iterate over, but that would make error messages uglier because we can either only print the (libseccomp-internal) syscall number or use seccomp_syscall_resolve_num_arch() to get the name or even make the vector a pair number/name, essentially duplicating everything again. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
This commit is contained in:
parent
1c52e344c4
commit
b90a435332
1 changed files with 41 additions and 0 deletions
|
@ -54,6 +54,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
|
||||||
|
|
||||||
|
@ -1632,8 +1633,48 @@ void chmod_(const Path & path, mode_t mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if __linux__
|
||||||
|
|
||||||
|
#define FORCE_SUCCESS(syscall) \
|
||||||
|
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(0), SCMP_SYS(syscall), 0) != 0) { \
|
||||||
|
seccomp_release(ctx); \
|
||||||
|
throw SysError("unable to add seccomp rule for " #syscall); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupSeccomp(void) {
|
||||||
|
scmp_filter_ctx ctx;
|
||||||
|
|
||||||
|
if ((ctx = seccomp_init(SCMP_ACT_ALLOW)) == NULL)
|
||||||
|
throw SysError("unable to initialize seccomp mode 2");
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
if (seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0) {
|
||||||
|
seccomp_release(ctx);
|
||||||
|
throw SysError("unable to add 32bit seccomp architecture");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FORCE_SUCCESS(chown);
|
||||||
|
FORCE_SUCCESS(fchown);
|
||||||
|
FORCE_SUCCESS(fchownat);
|
||||||
|
FORCE_SUCCESS(lchown);
|
||||||
|
|
||||||
|
if (seccomp_load(ctx) != 0) {
|
||||||
|
seccomp_release(ctx);
|
||||||
|
throw SysError("unable to load seccomp BPF program");
|
||||||
|
}
|
||||||
|
|
||||||
|
seccomp_release(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef FORCE_SUCCESS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int childEntry(void * arg)
|
int childEntry(void * arg)
|
||||||
{
|
{
|
||||||
|
setupSeccomp();
|
||||||
((DerivationGoal *) arg)->runChild();
|
((DerivationGoal *) arg)->runChild();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue