从文件加载 seccomp 规则

从文件加载 seccomp 规则

我正在尝试实现一个简单的容器。我希望用户能够在 profile.json 文件中指定列入白名单的系统调用。

profile.json 文件的示例内容:

{
"whitelisted_syscalls": ["read", "exit", "write", "accept"],
}

那么我的应用程序只会解析该文件并根据内容启用/禁用系统调用。

问题是它seccomp_rule_add要求用户使用SCMP_SYS宏。例如,为了允许read系统调用,我通常会调用:

seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);

并将SCMP_SYS(read)根据架构展开为整数。

答案1

libseccomp 与系统调用号一起工作;即使它没有要求您使用 SCMP_SYS(),您仍然需要使用宏而__NR_read不是文本名称。

不过,你可以使用seccomp_syscall_resolve_name() 来在运行时执行从系统调用名称到数字的转换。

(请注意,包括 32 位 x86 在内的一些架构在开始为 accept() 赋予自己的编号之前,曾经将其隐藏在多路复用的“socketcall”系统调用后面。)

答案2

以下 C 语言采用 \n 分隔的系统调用名称的 char*,并将其限制为仅这些调用。之前尝试使用增量锁定失败并被忽略。

static void seccomp_winch(char *list)
{
    char *str1, *token;
    char *saveptr1;
    int rc;
    uint32_t call;
    scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
    if (NULL == ctx) {
        perror("seccomp_init");
        exit(1);
    }

    for (str1 = list; ; str1 = NULL) {
        token = strtok_r(str1, split_token, &saveptr1);
        if (token == NULL)
            break;

        call = seccomp_syscall_resolve_name_rewrite(SCMP_ARCH_NATIVE, token);
        rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, call, 0);
        if (rc < 0) {
            printf("could not find syscall '%s'\n", token);
        }
    }

    rc =  seccomp_load(ctx);
    if (rc < 0) {
        perror("seccomp_load");
        exit(-rc);
    }
}

相关内容