int main(int argc, char *argv[])
{
	int rc;
	struct util_options opts;
	scmp_filter_ctx ctx = NULL;

	rc = util_getopt(argc, argv, &opts);
	if (rc < 0)
		goto out;

	ctx = seccomp_init(SCMP_ACT_KILL);
	if (ctx == NULL)
		return ENOMEM;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
			      SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO),
			      SCMP_A1(SCMP_CMP_NE, 0x0),
			      SCMP_A2(SCMP_CMP_LT, SSIZE_MAX));
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3,
			      SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO),
			      SCMP_A1(SCMP_CMP_NE, 0x0),
			      SCMP_A2(SCMP_CMP_LT, SSIZE_MAX));
	if (rc != 0)
		goto out;
	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3,
			      SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO),
			      SCMP_A1(SCMP_CMP_NE, 0x0),
			      SCMP_A2(SCMP_CMP_LT, SSIZE_MAX));
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
	if (rc != 0)
		goto out;

	rc = util_filter_output(&opts, ctx);
	if (rc)
		goto out;

out:
	seccomp_release(ctx);
	return (rc < 0 ? -rc : rc);
}
示例#2
0
void drop_privileges(void) {
    scmp_filter_ctx ctx = seccomp_init(DENY_ACTION);
    if (ctx == NULL) {
        return;
    }

    int rc = 0;
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_wait), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_pwait), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shmctl), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, SCMP_A1(SCMP_CMP_EQ, TIOCGWINSZ));
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, SCMP_A1(SCMP_CMP_EQ, TCGETS));

#ifdef MEMCACHED_DEBUG
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(readv), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0);

    if (settings.relaxed_privileges) {
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mkdir), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(access), 0);
    }
#endif

    if (rc != 0) {
        goto fail;
    }

    rc = seccomp_load(ctx);
    if (rc < 0) {
        goto fail;
    }

    seccomp_release(ctx);
    return;

fail:
    seccomp_release(ctx);
    fprintf(stderr, "Failed to set a seccomp profile on the main thread\n");
    exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
	int rc;
	struct util_options opts;
	scmp_filter_ctx ctx = NULL;

	rc = util_getopt(argc, argv, &opts);
	if (rc < 0)
		goto out;

	ctx = seccomp_init(SCMP_ACT_KILL);
	if (ctx == NULL)
		return ENOMEM;

	/* the syscall and argument numbers are all fake to make the test
	 * simpler */

	rc = seccomp_syscall_priority(ctx, 1000, 3);
	if (rc != 0)
		goto out;
	rc = seccomp_syscall_priority(ctx, 1001, 2);
	if (rc != 0)
		goto out;
	rc = seccomp_syscall_priority(ctx, 1002, 1);
	if (rc != 0)
		goto out;

	rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 2,
				    SCMP_A0(SCMP_CMP_EQ, 0),
				    SCMP_A1(SCMP_CMP_EQ, 1));
	if (rc != 0)
		goto out;
	rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 1,
				    SCMP_A0(SCMP_CMP_EQ, 0));
	if (rc != 0)
		goto out;
	rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 0);
	if (rc != 0)
		goto out;

	rc = util_filter_output(&opts, ctx);
	if (rc)
		goto out;

out:
	seccomp_release(ctx);
	return (rc < 0 ? -rc : rc);
}
示例#4
0
bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx,
			uint32_t action)
{
	int nr, ret;

	ret = seccomp_arch_exist(ctx, arch);
	if (arch && ret != 0) {
		ERROR("BUG: Seccomp: rule and context arch do not match (arch "
		      "%d): %s.",
		      arch, strerror(-ret));
		return false;
	}

	if (strncmp(line, "reject_force_umount", 19) == 0) {
		INFO("Setting Seccomp rule to reject force umounts.");
		ret = seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(umount2),
				1, SCMP_A1(SCMP_CMP_MASKED_EQ , MNT_FORCE , MNT_FORCE ));
		if (ret < 0) {
			ERROR("Failed (%d) loading rule to reject force "
			      "umount: %s.",
			      ret, strerror(-ret));
			return false;
		}
		return true;
	}

	nr = seccomp_syscall_resolve_name(line);
	if (nr == __NR_SCMP_ERROR) {
		WARN("Seccomp: failed to resolve syscall: %s.", line);
		WARN("This syscall will NOT be blacklisted.");
		return true;
	}
	if (nr < 0) {
		WARN("Seccomp: got negative for syscall: %d: %s.", nr, line);
		WARN("This syscall will NOT be blacklisted.");
		return true;
	}
	ret = seccomp_rule_add_exact(ctx, action, nr, 0);
	if (ret < 0) {
		ERROR("Failed (%d) loading rule for %s (nr %d action %d): %s.",
		      ret, line, nr, action, strerror(-ret));
		return false;
	}
	return true;
}
示例#5
0
int main() {
  printf("step 1: unrestricted\n");

  // ensure none of our children will ever be granted more priv
  // (via setuid, capabilities, ...)
  prctl(PR_SET_NO_NEW_PRIVS, 1);
  // ensure no escape is possible via ptrace
  prctl(PR_SET_DUMPABLE, 0);

  // Init the filter
  scmp_filter_ctx ctx;
  ctx = seccomp_init(SCMP_ACT_KILL); // default action: kill

  // setup basic whitelist
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
  
  // setup our rule
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 2, 
                        SCMP_A0(SCMP_CMP_EQ, 1),
                        SCMP_A1(SCMP_CMP_EQ, 2));

  // build and load the filter
  seccomp_load(ctx);
  printf("step 2: only 'write' and dup2(1, 2) syscalls\n");
  
  // Redirect stderr to stdout
  dup2(1, 2);
  printf("step 3: stderr redirected to stdout\n");

  // Duplicate stderr to arbitrary fd
  dup2(2, 42);
  printf("step 4: !! YOU SHOULD NOT SEE ME !!\n");

  // Success (well, not so in this case...)
  return 0;
}
示例#6
0
文件: main.c 项目: skeggsb/envytools
int main(int argc, char *argv[])
{
	char *filename = read_opts(argc, argv);

	/* set up an rnn context */
	rnn_init();
	rnndb = rnn_newdb();
	rnn_parsefile(rnndb, "fifo/nv_objects.xml");
	if (rnndb->estatus)
		demmt_abort();
	rnn_prepdb(rnndb);
	domain = rnn_finddomain(rnndb, "SUBCHAN");
	if (!domain)
		demmt_abort();

	rnndb_g80_texture = rnn_newdb();
	rnn_parsefile(rnndb_g80_texture, "graph/g80_texture.xml");
	if (rnndb_g80_texture->estatus)
		demmt_abort();
	rnn_parsefile(rnndb_g80_texture, "graph/gm107_texture.xml");
	if (rnndb_g80_texture->estatus)
		demmt_abort();
	rnn_prepdb(rnndb_g80_texture);

	rnndb_gf100_shaders = rnn_newdb();
	rnn_parsefile(rnndb_gf100_shaders, "graph/gf100_shaders.xml");
	if (rnndb_gf100_shaders->estatus)
		demmt_abort();
	rnn_prepdb(rnndb_gf100_shaders);

	gf100_shaders_ctx = rnndec_newcontext(rnndb_gf100_shaders);
	gf100_shaders_ctx->colors = colors;
	/* doesn't matter which, just needs to exist to make it
	 * possible to modify later.
	 */
	rnndec_varadd(gf100_shaders_ctx, "GF100_SHADER_KIND", "FP");

	rnndb_nvrm_object = rnn_newdb();
	rnn_parsefile(rnndb_nvrm_object, "../docs/nvrm/rnndb/nvrm_object.xml");
	if (rnndb_nvrm_object->estatus)
		demmt_abort();
	rnn_prepdb(rnndb_nvrm_object);

	tic_domain = rnn_finddomain(rnndb_g80_texture, "TIC");
	tic2_domain = rnn_finddomain(rnndb_g80_texture, "TIC2");
	tsc_domain = rnn_finddomain(rnndb_g80_texture, "TSC");

	gf100_sp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_SP_HEADER");
	gf100_fp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_FP_HEADER");
	if (!gf100_sp_header_domain || !gf100_fp_header_domain)
		demmt_abort();

	gk104_cp_header_domain = rnn_finddomain(rnndb, "GK104_COMPUTE_LAUNCH_DESC");
	if (!gk104_cp_header_domain)
		demmt_abort();

	if (filename)
	{
		close(0);
		if (open_input(filename) == NULL)
		{
			perror("open");
			exit(1);
		}
		free(filename);
	}

	if (pager_enabled)
	{
		int pipe_fds[2];
		pid_t pid;

		if (pipe(pipe_fds) < 0)
		{
			perror("pipe");
			demmt_abort();
		}

		pid = fork();
		if (pid < 0)
		{
			perror("fork");
			demmt_abort();
		}

		if (pid > 0)
		{
			char *less_argv[] = { "less", "-ScR", NULL };

			close(pipe_fds[1]);
			dup2(pipe_fds[0], 0);
			close(pipe_fds[0]);
			execvp(less_argv[0], less_argv);

			perror("exec");
			demmt_abort();
		}

		close(pipe_fds[0]);
		dup2(pipe_fds[1], 1);
		dup2(pipe_fds[1], 2);
		close(pipe_fds[1]);
	}

#ifdef LIBSECCOMP_AVAILABLE
	if (seccomp_level)
	{
		int rc;
		scmp_filter_ctx ctx;
		if (seccomp_level == 2)
			ctx = seccomp_init(SCMP_ACT_KILL);
		else
			ctx = seccomp_init(SCMP_ACT_TRACE(1234));
		if (!ctx)
		{
			fprintf(stderr, "seccomp_init failed\n");
			exit(1);
		}

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
				SCMP_A0(SCMP_CMP_EQ, 0));
		if (rc != 0)
			exit(1);
		seccomp_syscall_priority(ctx, SCMP_SYS(read), 254);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
				SCMP_A0(SCMP_CMP_LE, 2));
		if (rc != 0)
			exit(1);
		seccomp_syscall_priority(ctx, SCMP_SYS(write), 255);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 1,
				SCMP_A0(SCMP_CMP_EQ, 1));
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
		if (rc != 0)
			exit(1);

		rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 2,
				SCMP_A0(SCMP_CMP_EQ, 1),
				SCMP_A1(SCMP_CMP_EQ, 0x5401/*TCGETS*/));
		if (rc != 0)
			exit(1);

		rc = seccomp_load(ctx);
		if (rc != 0)
		{
			fprintf(stderr, "seccomp_load failed with error: %d\n", rc);
			exit(1);
		}

		seccomp_release(ctx);
	}
#endif

	mmt_decode(&demmt_funcs.base, NULL);
	fflush(stdout);

	fini_macrodis();
	demmt_cleanup_isas();
	rnndec_freecontext(gf100_shaders_ctx);
	rnn_freedb(rnndb);
	rnn_freedb(rnndb_g80_texture);
	rnn_freedb(rnndb_gf100_shaders);
	rnn_freedb(rnndb_nvrm_object);
	rnn_fini();

	return 0;
}
示例#7
0
void GenHash::calcGenHash()
{
    sandbox_init();

    // cannot excute execve
    prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
    kDebug() << "execve" << execve("ls",NULL,NULL);

    if (child_pid){

        KParts::ReadOnlyPart * part = qobject_cast<KParts::ReadOnlyPart *>(parent());

        QFile file(KFileDialog::getOpenFileName(KUrl("kfiledialog:///konqueror"), i18n("*"), part->widget(), i18n("Open File To make MD5.")));

        if (!file.open(QIODevice::ReadOnly))
        {
            return;
        }

        // TODO QFile
        //char s[1024];

        // write file content
        {
            close(pipe_fd[0]);
            QByteArray s = file.readAll();
            char *ch = s.data();
            if (write(pipe_fd[1], ch, s.size()) < 0) {
                perror("write");
            }
            close(pipe_fd[1]);
        }

        //read result
        {
            close(pipe_result_fd[1]);
            char result[128];
            if (read(pipe_result_fd[0], &result[0], 128) < 0){
                perror("read");
            }
            close(pipe_result_fd[0]);

            KMessageBox::information(part->widget(),i18n("Md5 : %1").arg(QString(QByteArray(result, 128))));
        }

    }else{

        scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
                                   SCMP_A0(SCMP_CMP_EQ, (scmp_datum_t)pipe_fd[0]),
                                   SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buff),
                                   SCMP_A2(SCMP_CMP_LE, 1024));
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
                                    SCMP_CMP(0, SCMP_CMP_EQ, (scmp_datum_t)pipe_result_fd[1]));

        seccomp_load(ctx);
        seccomp_release(ctx);

        calcMD5();
    }
}
示例#8
0
int disable_system_calls(struct worker_st *ws)
{
	int ret;
	scmp_filter_ctx ctx;

	ctx = seccomp_init(SCMP_ACT_KILL);
	if (ctx == NULL) {
		oclog(ws, LOG_DEBUG, "could not initialize seccomp");
		return -1;
	}

#define ADD_SYSCALL(name, ...) \
	ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(name), __VA_ARGS__); \
	/* libseccomp returns EDOM for pseudo-syscalls due to a bug */ \
	if (ret < 0 && ret != -EDOM) { \
		oclog(ws, LOG_DEBUG, "could not add " #name " to seccomp filter: %s", strerror(-ret)); \
		ret = -1; \
		goto fail; \
	}

	ADD_SYSCALL(time, 0);
	ADD_SYSCALL(gettimeofday, 0);
	ADD_SYSCALL(recvmsg, 0);
	ADD_SYSCALL(sendmsg, 0);
	ADD_SYSCALL(read, 0);
	ADD_SYSCALL(write, 0);
	ADD_SYSCALL(writev, 0);
	ADD_SYSCALL(send, 0);
	ADD_SYSCALL(recv, 0);

	/* it seems we need to add sendto and recvfrom
	 * since send() and recv() aren't real system
	 * calls.
	 */
	ADD_SYSCALL(sendto, 0);
	ADD_SYSCALL(recvfrom, 0);
	ADD_SYSCALL(select, 0);
	ADD_SYSCALL(alarm, 0);
	ADD_SYSCALL(close, 0);
	ADD_SYSCALL(exit, 0);
	ADD_SYSCALL(exit_group, 0);
	ADD_SYSCALL(socket, 0);
	ADD_SYSCALL(connect, 0);

	/* this we need to get the MTU from
	 * the TUN device */
	ADD_SYSCALL(ioctl, 1, SCMP_A1(SCMP_CMP_EQ, (int)SIOCGIFDSTADDR));
	ADD_SYSCALL(ioctl, 1, SCMP_A1(SCMP_CMP_EQ, (int)SIOCGIFADDR));
	ADD_SYSCALL(ioctl, 1, SCMP_A1(SCMP_CMP_EQ, (int)SIOCGIFMTU));

	ret = seccomp_load(ctx);
	if (ret < 0) {
		oclog(ws, LOG_DEBUG, "could not load seccomp filter");
		ret = -1;
		goto fail;
	}
	
	ret = 0;

fail:
	seccomp_release(ctx);
	return ret;
}
示例#9
0
void drop_worker_privileges(void) {
    scmp_filter_ctx ctx = seccomp_init(DENY_ACTION);
    if (ctx == NULL) {
        return;
    }

    int rc = 0;
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_wait), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_pwait), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(poll), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(readv), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpeername), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendmsg), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getrusage), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, SCMP_A1(SCMP_CMP_EQ, TIOCGWINSZ));

    // for spawning the LRU crawler
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clone), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(set_robust_list), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);

    // stat
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockname), 0);
    rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0);

    if (settings.shutdown_command) {
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tgkill), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tkill), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(gettid), 0);
    }

    if (settings.relaxed_privileges) {
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mkdir), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(access), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 0);
    } else {
        // stdout
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, 1));
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 1, SCMP_A0(SCMP_CMP_EQ, 1));
        // stderr
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, 2));
        rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 1, SCMP_A0(SCMP_CMP_EQ, 2));
    }

    if (rc != 0) {
        goto fail;
    }

    rc = seccomp_load(ctx);
    if (rc < 0) {
        goto fail;
    }

    seccomp_release(ctx);
    return;

fail:
    seccomp_release(ctx);
    fprintf(stderr, "Failed to set a seccomp profile on a worker thread\n");
    exit(EXIT_FAILURE);
}