最近遇到了一个和seccomp相关的问题,但还不清楚是什么,学习一下。
¶概要
seccomp是Linux kernel的一种计算安全机制,让进程只能够执行指定的系统调用。如果尝试执行不允许执行的系统调用,则程序会收到SIGKILL或SIGSYS信号。可以通过系统调用prctl(2)使用参数PR_SET_SECCOMP,或系统调用seccomp(2)开启seccomp模式。seccomp有两种模式,分别是严格模式SECCOMP_MODE_STRICT和过滤模式SECCOMP_MODE_FILTER。
OpenSSH、vsftpd、Chrome/Chromium、Docker等项目使用了seccomp。
¶严格模式 SECCOMP_MODE_STRICT
严格模式只允许调用read(2)、write(2)、_exit(2)(不包括exit_group(2))和sigreturn(2)。其他的系统调用会导致调用的线程退出,但进程只有一个线程时,整个程序会因为SIGKILL终止。严格模式对于数字处理应用程序非常有用,可能需要执行从管道或套接字读取的不受信任的字节码。
需要注意的是,调用线程不能够再调用sigprocmask(2),但可以使用sigreturn(2)阻塞除SIGKILL和SIGSTOP外的所有信号。这意味着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 | syscall(SYS_seccomp, SECCOMP_SET_MODE_STRICT, 0, NULL); |
¶过滤模式 SECCOMP_MODE_FILTER
允许使用BPF过滤系统调用,相比严格模式,更加灵活。
待完善。