2

PROBLEM: I'm trying to play with seccomp but I can't understand why gcc tells me that seccomp() function call has an implicit declaration.

#define _GNU_SOURCE
#include <stddef.h> // offsetof
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/audit.h> // arch
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <sys/syscall.h> // syscall numbers

struct sock_filter  bpfcode[] = {

    /* validate the architecture */
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 0, 7),
    /* load syscall number in the accumulator */
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof (struct seccomp_data, nr))),
    /* check if the syscall number is allowed */
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_nanosleep, 5, 0), // for sleep
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_exit, 4, 0),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_exit_group, 3, 0),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_write, 2, 0),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_read, 1, 0),
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_rt_sigreturn, 0, 1),
    /* allow the sys call */
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP)
};

struct sock_fprog  bpf = {
    .len = (unsigned short)( sizeof bpfcode / sizeof bpfcode[0] ),
    .filter = bpfcode 
};

int main(int argc, char **argv)
{
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
        printf("prctl no_new_privs\n");
        _exit(EXIT_FAILURE);
    }
    if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &bpf)) {
        printf("seccomp");
        exit(EXIT_FAILURE);
    } 
    sleep(2);    
    return 0;
}

WARNING/ERROR: this is the gcc output when I try to compile the program.

s.c: In function ‘main’:
    s.c:45:6: warning: implicit declaration of function ‘seccomp’ [-Wimplicit-function-declaration]
      if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &bpf)) {
          ^~~~~~~
    /tmp/ccYo4APk.o: In function `main':
    s.c:(.text+0x65): undefined reference to `seccomp'
    collect2: error: ld returned 1 exit status

QUESTION: what else should I include to make it work?

EDIT: why this works and the first didn't? syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &bpf)

pchaigno
  • 11,313
  • 2
  • 29
  • 54
Maicake
  • 1,046
  • 10
  • 34

1 Answers1

5

It's a known issue: there is no glibc wrapper for the seccomp syscall.

You might want to use prctl(2) instead to load the BPF program, for two reasons:

  1. a glibc wrapper is available for prctl(2)
  2. the seccomp(2) syscall is only available on Linux v3.5+.

Here's how to:

prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bpf);
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
pchaigno
  • 11,313
  • 2
  • 29
  • 54
  • Regarding point 2. in the link is reported that "The seccomp() system call first appeared in Linux 3.17." anyway I have 4.18.0-25 kernel version. but still it doesn't work. I've also seen that in the directory seccomp/samples (https://github.com/torvalds/linux/blob/master/samples/seccomp/user-trap.c#L26-L30) there is a wrapper definition of the syscall , should I do the same? – Maicake Aug 05 '19 at 08:58
  • I'm wrong 3.17 is just reffering to the syscall not to the wrapper. Howevere the problem is the same, I'm running 4.18 > 3.5 and I can't call the wrapper function. :/ – Maicake Aug 05 '19 at 09:09
  • With 4.18, there is a seccomp(2) system call but still no seccomp() wrapper in glibc. You should use prctl() instead. Is that not working? If it's not working, what's the error message? – pchaigno Aug 05 '19 at 09:33
  • Ah ok thanks so still there is no wrapper. I mean it works if I call seccomp with syscall or if I use prctl. But since they introduced seccomp syscall after prctl and since with seccomp you can use also flags as arguments I'd like to use seccomp syscall. Anyway how can I list all the glibc functions? And can I check if in the last version of glibc they added new wrappers? – Maicake Aug 05 '19 at 10:28