3

我刚刚开始学习 seccomp 过滤器,我正在使用libseccomp v2.4.4。我试图编写一个基本的白名单过滤器,它只允许写入名为的文件file1,但我在STDOUT. 这是我的代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <seccomp.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
        FILE *fil = fopen("file1", "w");
        scmp_filter_ctx filter = seccomp_init(SCMP_ACT_KILL);

        if (filter==NULL || NULL==fil)
                goto End1;

        int chk1 = seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
                                    SCMP_A0(SCMP_CMP_EQ, fileno(fil)));
        int chk2 = seccomp_load(filter);
        if (chk1<0 || chk2<0)
                goto End;

        fprintf(stdout,"Filter did not work correctly\n");
        fprintf(fil,"Filter worked correctly\n");

End:
        seccomp_release(filter); //releasing filter before closing file
        fclose(fil);

End1:
        return 0;
}

此外,我在file1. 我只是一个初学者,对这里的很多事情都不确定,因为我是根据自己的理解而不是参考来编写代码的。似乎是什么问题?


编辑:我完全删除了过滤器并简单地执行了

int main(void)
{
        FILE *fil = fopen("file1", "w");

        fprintf(stdout,"Filter did not work correctly\n");
        fprintf(fil,"Filter worked correctly\n");

End:
        fclose(fil);

End1:
        return 0;
}

跟踪这一点,我观察到 syscalls fstatclose正如@pchaigno 下面的答案中提到的那样,另外mmapmunmap正在被调用。所以我必须允许这些系统调用来实现预期的行为。

4

1 回答 1

4

调试

跟踪您的应用程序将揭示问题:

$ strace ./test
[...]
seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=12, filter=0x55ace60a6600}) = 0
fstat(1,  <unfinished ...>)             = ?
+++ killed by SIGSYS (core dumped) +++
Bad system call (core dumped)

允许最少的系统调用集

您需要允许更多的系统调用,而不仅仅是write(2)为了让程序结束而没有错误。

您需要fstat(2)for fprintf()close(2)forfclose()exit_group(2)to 结束该过程。

拒绝系统调用而不是杀死进程

此外,如果您希望程序在未经授权的系统调用后继续运行,则不应使用SCMP_ACT_KILL. SCMP_ACT_ERRNO(EPERM)在这种情况下可能更合适。

结果

int main(void) {
        FILE *fil = fopen("file1", "w");
        scmp_filter_ctx filter = seccomp_init(SCMP_ACT_ERRNO(EPERM));
        if (filter == NULL || NULL == fil)
                return 1;
        if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ,fileno(fil))) < 0)
                goto err;
        if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0) < 0)
                goto err;
        if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(close), 0) < 0)
                goto err;
        if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0) < 0)
                goto err;
        if (seccomp_load(filter) < 0)
                goto err;
        fprintf(stdout, "Filter did not work correctly\n");
        fprintf(fil, "Filter worked correctly\n");
err:
        seccomp_release(filter); //releasing filter before closing file
        fclose(fil);
        return 0;
}

给我们:

$ ./test; echo file1
Filter worked correctly
于 2021-06-10T09:33:32.413 回答