在内核探针 (kprobes) 中,eBPF 虚拟机对系统调用参数和返回值具有只读访问权限。
然而,eBPF 程序将有它自己的返回码。可以应用 seccomp 配置文件来捕获 BPF(不是 eBPF;感谢@qeole)返回代码并在执行期间中断系统调用。
允许的运行时修改是:
-
SECCOMP_RET_KILL: 立即用SIGSYS 杀死
-
SECCOMP_RET_TRAP:发送一个可捕获的SIGSYS,提供模拟系统调用的机会
-
SECCOMP_RET_ERRNO:强制errno值
-
SECCOMP_RET_TRACE:将产量决策设置为 ptracer 或将 errno 设置为 -ENOSYS
-
SECCOMP_RET_ALLOW:允许
https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
SECCOMP_RET_TRACE 方法允许修改执行的系统调用、参数或返回值。这取决于体系结构,并且对强制外部引用的修改可能会导致 ENOSYS 错误。
它通过将执行传递给等待的用户空间 ptrace 来做到这一点,它能够修改被跟踪的进程内存、寄存器和文件描述符。
跟踪器需要调用 ptrace,然后调用 waitpid。一个例子:
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
http://man7.org/linux/man-pages/man2/ptrace.2.html
当waitpid 返回时,根据status 的内容,可以使用PTRACE_GETEVENTMSG ptrace 操作检索seccomp 返回值。这将检索 seccomp SECCOMP_RET_DATA 值,这是 BPF 程序设置的 16 位字段。示例:
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
可以在继续操作之前在内存中修改系统调用参数。您可以使用PTRACE_SYSCALL 步骤执行单个系统调用进入或退出。恢复执行前可以在用户空间修改 Syscall 返回值;底层程序将无法看到系统调用返回值已被修改。
一个示例实现:
Filter and Modify System Calls with seccomp and ptrace