我正在尝试实现一个简单的容器。我希望用户能够在 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);
}
}