#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: seccomp.c,v 1.29 2024/09/29 16:49:25 christos Exp $")
#endif
#if HAVE_LIBSECCOMP
#include <seccomp.h>
#include <sys/prctl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <termios.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#define DENY_RULE(call) \
do \
if (seccomp_rule_add (ctx, SCMP_ACT_KILL, SCMP_SYS(call), 0) == -1) \
goto out; \
while (0)
#define ALLOW_RULE(call) \
do \
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(call), 0) == -1) \
goto out; \
while (0)
#define ALLOW_IOCTL_RULE(param) \
do \
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, \
SCMP_CMP(1, SCMP_CMP_EQ, (scmp_datum_t)param, \
(scmp_datum_t)0)) == -1) \
goto out; \
while (0)
static scmp_filter_ctx ctx;
int
enable_sandbox(void)
{
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
return -1;
#if 0
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
return -1;
#endif
ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL)
return -1;
ALLOW_RULE(access);
ALLOW_RULE(brk);
ALLOW_RULE(close);
ALLOW_RULE(dup2);
ALLOW_RULE(exit);
ALLOW_RULE(exit_group);
#ifdef __NR_faccessat
ALLOW_RULE(faccessat);
#endif
ALLOW_RULE(fcntl);
ALLOW_RULE(fcntl64);
#ifdef __NR_fstat
ALLOW_RULE(fstat);
#endif
ALLOW_RULE(fstat64);
#ifdef __NR_fstatat64
ALLOW_RULE(fstatat64);
#endif
ALLOW_RULE(futex);
ALLOW_RULE(getdents);
#ifdef __NR_getdents64
ALLOW_RULE(getdents64);
#endif
#ifdef FIONREAD
ALLOW_IOCTL_RULE(FIONREAD);
#endif
#ifdef TIOCGWINSZ
ALLOW_IOCTL_RULE(TIOCGWINSZ);
#endif
#ifdef TCGETS
ALLOW_IOCTL_RULE(TCGETS);
#endif
ALLOW_RULE(lseek);
ALLOW_RULE(_llseek);
ALLOW_RULE(lstat);
ALLOW_RULE(lstat64);
ALLOW_RULE(madvise);
ALLOW_RULE(mmap);
ALLOW_RULE(mmap2);
ALLOW_RULE(mprotect);
ALLOW_RULE(mremap);
ALLOW_RULE(munmap);
#ifdef __NR_newfstatat
ALLOW_RULE(newfstatat);
#endif
ALLOW_RULE(open);
ALLOW_RULE(openat);
ALLOW_RULE(pread64);
ALLOW_RULE(read);
ALLOW_RULE(readlink);
#ifdef __NR_readlinkat
ALLOW_RULE(readlinkat);
#endif
ALLOW_RULE(rt_sigaction);
ALLOW_RULE(rt_sigprocmask);
ALLOW_RULE(rt_sigreturn);
ALLOW_RULE(select);
ALLOW_RULE(stat);
ALLOW_RULE(statx);
ALLOW_RULE(stat64);
ALLOW_RULE(sysinfo);
ALLOW_RULE(umask);
ALLOW_RULE(getpid);
ALLOW_RULE(getrandom);
ALLOW_RULE(unlink);
ALLOW_RULE(utimes);
ALLOW_RULE(write);
ALLOW_RULE(writev);
#if 0
ALLOW_RULE(gettid);
ALLOW_RULE(rt_sigtimedwait);
#endif
#if 0
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) == -1)
goto out;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) == -1)
goto out;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) == -1)
goto out;
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) == -1)
goto out;
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) == -1)
goto out;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
SCMP_CMP(0, SCMP_CMP_EQ, 2)) == -1)
goto out;
#endif
#if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 2,
SCMP_CMP32(0, SCMP_CMP_EQ, PR_SET_VMA),
SCMP_CMP64(1, SCMP_CMP_EQ, PR_SET_VMA_ANON_NAME)) == -1)
goto out;
#endif
if (seccomp_load(ctx) == -1)
goto out;
seccomp_release(ctx);
return 0;
out:
seccomp_release(ctx);
return -1;
}
#endif