0

I have implemented libseccomp restrict certain system calls for a process. It is the first program that I have written. However, when I debugged it using strace, it appears that libseccomp is not functioning as expected.

Following is libseccomp code:

#include <stdio.h>
#include <seccomp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include "../runner.h"

// Function to apply seccomp rules
int python_seccomp_rules(struct config *_config)
{
    // Syscalls blacklist array
    int syscalls_blacklist[] = {
        SCMP_SYS(fork), SCMP_SYS(vfork), SCMP_SYS(kill)
    };

    // Initializing seccomp context
    scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
    if (!ctx)
    {
        return LOAD_SECCOMP_FAILED;
    }

    // Blacklist specified syscalls
    int syscalls_blacklist_length = sizeof(syscalls_blacklist) / sizeof(int);
    for (int i = 0; i < syscalls_blacklist_length; i++)
    {
        if (seccomp_rule_add(ctx, SCMP_ACT_KILL, syscalls_blacklist[i], 0) != 0)
        {
            seccomp_release(ctx);
            return LOAD_SECCOMP_FAILED;
        }
    }

    // Deny socket calls, python will be killed immediately
    if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 0) != 0)
    {
        seccomp_release(ctx);
        return LOAD_SECCOMP_FAILED;
    }

    // Add extra rule for execve
    if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_NE, (scmp_datum_t)(_config->exe_path))) != 0)
    {
        seccomp_release(ctx);
        return LOAD_SECCOMP_FAILED;
    }

    // Deny "w" and "rw" modes using open
    if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) != 0)
    {
        seccomp_release(ctx);
        return LOAD_SECCOMP_FAILED;
    }
    if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) != 0)
    {
        seccomp_release(ctx);
        return LOAD_SECCOMP_FAILED;
    }

    // Deny "w" and "rw" modes using openat
    if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(openat), 1, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) != 0)
    {
        seccomp_release(ctx);
        return LOAD_SECCOMP_FAILED;
    }
    if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(openat), 1, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) != 0)
    {

When I traced it using strace command, I got the following output:

6885  15:57:14 seccomp(SECCOMP_SET_MODE_STRICT, 0x1, NULL) = -1 EINVAL (Invalid argument)
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, NULL) = -1 EFAULT (Bad address)
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, NULL) = -1 EFAULT (Bad address)
6885  15:57:14 seccomp(SECCOMP_GET_ACTION_AVAIL, 0, [SECCOMP_RET_LOG]) = 0
6885  15:57:14 seccomp(SECCOMP_GET_ACTION_AVAIL, 0, [SECCOMP_RET_KILL_PROCESS]) = 0
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_SPEC_ALLOW, NULL) = -1 EFAULT (Bad address)
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NEW_LISTENER, NULL) = -1 EFAULT (Bad address)
6885  15:57:14 seccomp(SECCOMP_GET_NOTIF_SIZES, 0, {seccomp_notif=80, seccomp_notif_resp=24, seccomp_data=64}) = 0
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC_ESRCH, NULL) = -1 EFAULT (Bad address)
6885  15:57:14 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0
6885  15:57:14 seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=30, filter=0x55a7aaa8b490}) = 0

Thanks in advance!

  • 1
    Not sure what would be your expected behavior, but have you considered the following from the manual of `seccomp_rule_add`: "The newly added filter rule does not take effect until the entire filter is loaded into the kernel using seccomp_load (3)." ? – skandigraun Jul 02 '23 at 17:46

0 Answers0