clinuxseccomp

I load a seccomp filter to disallow fork(), but can still use fork() with no problem


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!


Solution

  • 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.