0%

seccomp

最近遇到了一个和seccomp相关的问题,但还不清楚是什么,学习一下。

概要

seccomp是Linux kernel的一种计算安全机制,让进程只能够执行指定的系统调用。如果尝试执行不允许执行的系统调用,则程序会收到SIGKILLSIGSYS信号。可以通过系统调用prctl(2)使用参数PR_SET_SECCOMP,或系统调用seccomp(2)开启seccomp模式。seccomp有两种模式,分别是严格模式SECCOMP_MODE_STRICT和过滤模式SECCOMP_MODE_FILTER

OpenSSHvsftpdChrome/ChromiumDocker等项目使用了seccomp

严格模式 SECCOMP_MODE_STRICT

严格模式只允许调用read(2)write(2)_exit(2)(不包括exit_group(2))和sigreturn(2)。其他的系统调用会导致调用的线程退出,但进程只有一个线程时,整个程序会因为SIGKILL终止。严格模式对于数字处理应用程序非常有用,可能需要执行从管道或套接字读取的不受信任的字节码。

需要注意的是,调用线程不能够再调用sigprocmask(2),但可以使用sigreturn(2)阻塞除SIGKILLSIGSTOP外的所有信号。这意味着alarm(2)(举例)不能用于限制程序的执行时间。此外,为了确保能终止程序,必须使用SIGKILL。通过向timer_create(2)传递SIGEV_SIGNAL参数,并且sigev_signo设置为SIGKILL可以完成这个。或者使用setrlimit(2)设置RLIMIT_CPU的硬限制。

使用如下代码开启严格模式。如果使用seccomp(2),第二个参数flags必须为0,第三个参数args必须为NULL。kernel配置需要打开CONFIG_SECCOMP

1
2
3
syscall(SYS_seccomp, SECCOMP_SET_MODE_STRICT, 0, NULL);
// 等价于
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);

过滤模式 SECCOMP_MODE_FILTER

允许使用BPF过滤系统调用,相比严格模式,更加灵活。

待完善。

参考