linux - eBPF 可以修改系统调用的返回值或参数吗?

标签 linux system-calls bpf ebpf

为了模拟某些行为,我想将探测器附加到系统调用并在传递某些参数时修改返回值。或者,在函数成为进程之前修改函数的参数也足够了。

这可以用 BPF 实现吗?

最佳答案

在内核探测 (kprobes) 中,eBPF 虚拟机对系统调用参数和返回值具有只读访问权限。

然而,eBPF 程序将有自己的返回码。可以应用捕获 BPF(不是 eBPF;感谢@qeole)返回代码并在执行期间中断系统调用的 seccomp 配置文件。

允许的运行时修改是:

  • 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 来实现,它能够修改跟踪的进程内存、寄存器和文件描述符。

tracer 需要调用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 步骤执行单个系统调用进入或退出。在恢复执行之前,可以在用户空间修改系统调用返回值;底层程序将无法看到系统调用返回值已被修改。

一个示例实现: Filter and Modify System Calls with seccomp and ptrace

关于linux - eBPF 可以修改系统调用的返回值或参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43003805/

相关文章:

c++ - 如何从 makefile 在 Linux 上安装程序?

c - 如何从内核空间确定 PID 位于哪些 namespace 中?

c++ - 关于在 CentOS-6.5 上安装 gcc-6.* 的问题

linux - Iptables 通过 VPN 转发

linux - 在 crontab 中运行脚本

linux - Linux 上有用于创建环回设备的 golang 库吗?

linux - 禁用 GCC 优化后不会发生 __kernel_vsyscall() 崩溃

C - 使用暴力搜索 64 位 Linux 内核中的系统调用表

networking - BPF:sock_ops 相当于 UDP 套接字