I'm trying to create a seccomp filter that would blacklist the use of fork(). This is my code:
#include <seccomp.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(void) {
int rc = -1;
int pid_t;
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
// possible issue for torsocks: needs arg count
rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(fork), 0);
printf("seccomp rule add return value: %d\n", rc);
rc = seccomp_load(ctx);
printf("seccomd_load return value: %d\n", rc);
pid_t = fork();
printf("%d\n", pid_t);
seccomp_release(ctx);
return 0;
}
I compile like so:
hc01@HC01:~/torsocks$ gcc test_seccomp.c -lseccomp
Then run to get the following output:
hc01@HC01:~/torsocks$ ./a.out
seccomp rule add return value: 0
seccomd_load return value: 0
15384
0
Implying that I was able to successfully fork and seccomp_add_rule and seccomp_load are running successfully. Can someone help me understand what I'm doing wrong? Thanks!
fork()
from glibc is likely actually using the system call clone
instead of fork
, see man fork
.
You can verify this by having a look at strace ./a.out
.
Therefore try:
rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(clone), 0);
instead.
You should in any case default-block and not default-allow syscalls, because otherwise you would need to consider all existing syscalls and whether they can have the undesired effect (e.g. for creating a child process there would be at least vfork
in addition to fork
and clone
) and also because new kernel versions may add arbitrary syscalls which could again produce the undesired effect.