Geo*_*lly 5 linux system-calls bpf ebpf
为了模拟某些行为,我想将探测附加到系统调用,并在传递某些参数时修改返回值.或者,在函数处理之前修改函数的参数也就足够了.
这可能与BPF有关吗?
在内核探测器(kprobes)中,eBPF虚拟机具有对syscall参数和返回值的只读访问权限.
但是,eBPF程序将拥有自己的返回代码.可以应用一个seccomp配置文件来捕获BPF(NOT eBPF;感谢@qeole)返回码并在执行期间中断系统调用.
允许的运行时修改是:
SECCOMP_RET_KILL:立即杀死 SIGSYSSECCOMP_RET_TRAP:发送一个catlecble SIGSYS,有机会模拟系统调用SECCOMP_RET_ERRNO:强制errno值SECCOMP_RET_TRACE:屈服决定ptracer或设置errno为-ENOSYSSECCOMP_RET_ALLOW:允许https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
该SECCOMP_RET_TRACE方法允许修改执行的系统调用,参数或返回值.这取决于体系结构,强制外部引用的修改可能会导致ENOSYS错误.
它通过将执行传递给等待的用户空间ptrace来实现,ptrace能够修改跟踪的进程内存,寄存器和文件描述符.
跟踪器需要调用ptrace然后调用waitpid.一个例子:
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
Run Code Online (Sandbox Code Playgroud)
http://man7.org/linux/man-pages/man2/ptrace.2.html
当waitpid返回时,根据的内容status,可以通过检索返回的Seccomp值PTRACE_GETEVENTMSGptrace的操作.这将检索seccomp SECCOMP_RET_DATA值,该值是BPF程序设置的16位字段.例:
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
Run Code Online (Sandbox Code Playgroud)
在继续操作之前,可以在内存中修改Syscall参数.您可以使用该PTRACE_SYSCALL步骤执行单个系统调用条目或退出.在恢复执行之前,可以在用户空间中修改Syscall返回值; 底层程序将无法看到系统调用返回值已被修改.
示例实现: 使用seccomp和ptrace过滤和修改系统调用
我相信将 eBPF 附加到 kprobes/kretprobes 可以让你读取函数参数和返回值,但你不能篡改它们。我不是 100% 确定;要求确认的好地方是 IO Visor 项目邮件列表或 IRC 频道(irc.oftc.net 上的#iovisor)。
作为替代解决方案,我知道您至少可以使用strace和-e选项更改系统调用的返回值。引用手册页:
Run Code Online (Sandbox Code Playgroud)-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr] Perform syscall tampering for the specified set of syscalls.
此外,如果您感兴趣的话,在 Fosdem 2017 上有一个关于此的演示和故障注入。这是幻灯片中的一个示例命令:
strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt
Run Code Online (Sandbox Code Playgroud)
编辑:正如 Ben 所说,kprobes 和跟踪点上的 eBPF 绝对是只读的,用于跟踪和监控用例。我也在 IRC 上得到了确认。
| 归档时间: |
|
| 查看次数: |
1595 次 |
| 最近记录: |