如eigenstate.org 和SECCOMP (2) 中所述:
调用线程被允许进行的唯一系统调用
make 是 read(2), write(2), _exit(2) (但不是 exit_group(2)),
和 sigreturn(2)。其他系统调用导致交付
SIGKILL 信号。
因此,人们期望_exit() 可以工作,但它是一个调用exit_group(2) 的包装函数,这在严格模式下是不允许的([1], [2]),因此进程被终止。
它甚至在exit(2) - Linux man page中被报道:
在直到 2.3 版的 glibc 中,_exit() 包装函数调用了同名的内核系统调用。从 glibc 2.3 开始,包装函数调用 exit_group(2),以终止进程中的所有线程。
return 语句也会发生同样的情况,它最终会以与 _exit() 非常相似的方式终止您的进程。
跟踪该过程将提供进一步的确认(要显示此信息,您必须不设置 PR_SET_SECCOMP;只需评论 prctl()),对于两种非工作情况,我得到了类似的输出:
linux12:/home/users/grad1459>gcc seccomp.c -o seccomp
linux12:/home/users/grad1459>strace ./seccomp
execve("./seccomp", ["./seccomp"], [/* 24 vars */]) = 0
brk(0) = 0x8784000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb775f000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=97472, ...}) = 0
mmap2(NULL, 97472, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7747000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220\226\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1730024, ...}) = 0
mmap2(NULL, 1739484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xdd0000
mmap2(0xf73000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a3) = 0xf73000
mmap2(0xf76000, 10972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xf76000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7746000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7746900, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xf73000, 8192, PROT_READ) = 0
mprotect(0x8049000, 4096, PROT_READ) = 0
mprotect(0x16e000, 4096, PROT_READ) = 0
munmap(0xb7747000, 97472) = 0
exit_group(0) = ?
linux12:/home/users/grad1459>
如你所见,exit_group() 被调用,说明一切!
现在正如你所说的那样,“SYS_exit equals __NR_exit”;例如它定义在mit.syscall.h:
#define SYS_exit __NR_exit
所以最后两个调用是等价的,即你可以使用你喜欢的那个,输出应该是这样的:
linux12:/home/users/grad1459>gcc seccomp.c -o seccomp && ./seccomp ; echo "${?}"
0
PS
您当然可以自己定义 filter 并使用:
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter);
如 eigenstate 链接中所述,允许 _exit()(或者,严格来说,exit_group(2)),但只有在您确实需要并且知道自己在做什么时才这样做。