Search code examples
gosystem-callsptraceseccomp

Is it possible to apply a Linux kernel SECCOMP profile from a Go process?


I am trying to implement an system call tracer with the support of kernel SECCOMP filters to reduce the overhead by filtering a few syscall types.

All the implementations I have found are in C, I am not able to figure how to map it to Go due to the special considerations with Go threading/go-routines and fork().

The sample code (C):

if ((pid = fork()) == 0) {

    ptrace(PTRACE_TRACEME, 0, 0, 0);
    /* To avoid the need for CAP_SYS_ADMIN */
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
        perror("prctl(PR_SET_NO_NEW_PRIVS)");
        return 1;
    }
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) {
        perror("when setting seccomp filter");
        return 1;
    }
    kill(getpid(), SIGSTOP);
    return execvp(argv[1], argv + 1);

After some research I have found that in order to perform a fork() like function in Go Lang we can use syscall.ForkExec or exec.Command, but both seem to be limited to the set of pre-exec operations that can be configured through the parameter syscall.SysProcAttr, while it provides support for the PTRACE_TRACEME call, it doesn't provide any support for the prctl() required for SECCOMP.

Is there some way to launch a "ptraceable" "seccomped" child process from a GoLang generated process ?


Solution

  • There are two libraries one can use for this:

    1. https://godoc.org/github.com/tfogal/ptrace - Package ptrace provides an interface to the ptrace system call.
    2. https://godoc.org/github.com/seccomp/libseccomp-golang - Package seccomp provides bindings for libseccomp, a library wrapping the Linux seccomp syscall. Seccomp enables an application to restrict system call use for itself and its children.

    Disclaimer: I am a c programmer, and have contributed to libseccomp; but golang is not my specialty so I am not sure what an equivalent of your sample code would be in that language.