linux 安全系列目录 - seccomp安全模块问题排查

linux 安全系列目录 - seccomp

涉及seccomp安全模块问题时,可以参照本文档案例进行扩展分析,可以多访问文中的链接,很有用。

security

一、Seccomp沙箱安全机制

通过使用libseccomp,开发人员可以定义一组允许的系统调用规则,从而限制应用程序的系统调用(system call)集合,阻止对潜在危险的系统调用的调用。它最初被用于 cpushare 这个项目,让人们可以出租自己空闲的 cpu cycle 来执行未受信任代码(untrusted code)。这个 feature 本身并不是一个沙盒 (sandbox),它只是一种减少 Linux 内核暴露的机制,是构建一个安全的沙盒的重要组成部分。其中,沙箱bwrap也会使用它。

安全计算模式 seccomp(Secure Computing Mode)是自 Linux 2.6.10 之后引入到 kernel 的特性。一切都在内核中完成,不需要额外的上下文切换,所以不会造成性能问题。目前 在 Docker 和 Chrome 中广泛使用。使用 seccomp,可以定义系统调用白名单和黑名单,可以 定义出现非法系统调用时候的动作,比如结束进程或者使进程调用失败。

seccomp机制用于限制应用程序可以使用的系统调用,增加系统的安全性。

在/proc/${pid}/status文件中的Seccomp字段可以看到进程的Seccomp。

二、安装依赖包

sudo apt install libseccomp-dev libseccomp2 seccomp

三、Seccomp Strict Mode

使用prctl来设置程序的seccomp为strict模式,仅允许read、write、_exit和sigreturn四个系统调用。当调用未在seccomp白名单中的系统调用后,应用程序会被kill。

#include <stdio.h>         /* printf */
#include <sys/prctl.h>     /* prctl */
#include <linux/seccomp.h> /* seccomp's constants */
#include <unistd.h>        /* dup2: just for test */

int main() {
  printf("step 1: unrestricted\n");

  // Enable filtering
  prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
  printf("step 2: only 'read', 'write', '_exit' and 'sigreturn' syscalls\n");
  
  // Redirect stderr to stdout
  dup2(1, 2);
  printf("step 3: !! YOU SHOULD NOT SEE ME !!\n");

  // Success (well, not so in this case...)
  return 0; 
}

四、Seccomp Filter Mode (Seccomp-BPF) - 推荐

基于prctl系统调用的seccomp机制不够灵活,在linux 3.5之后引入了基于BPF的可定制的系统调用过滤功能

#include <stdio.h>   /* printf */
#include <unistd.h>  /* dup2: just for test */
#include <seccomp.h> /* libseccomp */

int main() {
  printf("step 1: unrestricted\n");

  // Init the filter
  scmp_filter_ctx ctx;
  ctx = seccomp_init(SCMP_ACT_KILL); // default action: kill

  // setup basic whitelist
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
  
  // setup our rule
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 2, 
                        SCMP_A0(SCMP_CMP_EQ, 1),
                        SCMP_A1(SCMP_CMP_EQ, 2));

  // build and load the filter
  seccomp_load(ctx);
  printf("step 2: only 'write' and dup2(1, 2) syscalls\n");
  
  // Redirect stderr to stdout
  dup2(1, 2);
  printf("step 3: stderr redirected to stdout\n");

  // Duplicate stderr to arbitrary fd
  dup2(2, 42);
  printf("step 4: !! YOU SHOULD NOT SEE ME !!\n");

  // Success (well, not so in this case...)
  return 0; 
}

五、有用资源

六、总结

seccomp是一种Linux内核特性,允许限制进程可以执行的系统调用,以增加应用程序的安全性。总的来说,libseccomp是一个强大的工具,可用于在Linux系统上实施安全策略,并限制应用程序的系统调用。在很多的应用中都有体现,如 flatpak, docker, google, systemd,linux-user-chroot