系统调用 openat 和 sys_enter_openat 有什么区别?
我看到 python BCC 实现 系统调用 __x64_sys_openat
用于附加 kprobe,但是在 libbpf 实现 kprobe 附加到 <代码>sys_enter_openat。似乎都捕获了 openat()
系统调用,我用 cat file.txt
对其进行了测试。
它们之间有什么区别?而哪一种使用起来更可靠呢?
I see for python BCC implementation the syscall __x64_sys_openat
is used to attach a kprobe, however in libbpf implementation a kprobe is attached to sys_enter_openat
. It seems both capture openat()
syscall, I tested it with cat file.txt
.
What is the difference between them? And which one is more reliable to use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
__x64_sys_openat
是Linux 内核中的某个函数的名称,BCC 将 kprobe 附加到该函数。sys_enter_openat
是 Linux 中跟踪点的名称,这意味着这是一个(或多或少)稳定的接口,您可以通过它挂钩进行跟踪,包括使用 eBPF 程序。您可以通过列出/sys/kernel/debug/tracing/events/
下的条目来查看系统上可用的跟踪点。我认为 BCC 也有一个名为 tplist 的实用程序来帮助解决这个问题。如果可以选择,我建议尽可能在跟踪点处挂钩,因为它们往往比内核内部更稳定:__x64_sys_openat 的参数或该函数的名称可能会在不同的内核版本之间发生变化例如;或者名称会在其他架构上发生变化,等。但是,跟踪点不太可能改变。请注意,对于具有 CO-RE 的 eBPF,内核内部的不稳定性有所缓解。
那么并不总是可以挂钩到跟踪点:您只能使用内核中现有的跟踪点之一。如果您想挂钩到另一个不存在跟踪点的随机函数(并且假设该函数在编译时未内联 - 通过在
/proc/kallsyms
中查找它来检查它),那么您想要使用 kprobe。有时您还需要额外注意您挂钩的位置。例如,对于安全用例(即阻止系统调用),系统调用跟踪点(显然,或相应的内核函数)并不总是最好的挂钩点,因为它们可能会让您容易受到 TOCTOU 攻击。 LSM 挂钩可能是该用例的一个很好的解决方案。
__x64_sys_openat
is the name of some function in the Linux kernel, to which BCC attaches a kprobe.sys_enter_openat
is the name of a tracepoint in Linux, meaning that this is a (more or less) stable interface to which you can hook for tracing, including with an eBPF program. You can see the available tracepoints on your system by listing the entries under/sys/kernel/debug/tracing/events/
. I think BCC also has a utility calledtplist
to help with it.When given the choice, I would recommend hooking at tracepoints if possible, because they tend to be more stable than kernel internals: The parameters for
__x64_sys_openat
, or the name of that function, could change between different kernel versions for example; or the name would change on an other architecture, et cætera. However, the tracepoint is unlikely to change. Note that the instability of kernel's internals is somewhat mitigated for eBPF with CO-RE.Then it is not always possible to hook to a tracepoint: You can only use one of the existing tracepoints from the kernel. If you want to hook to another random function where no tracepoint is present (and assuming this function was not inlined at compilation time - check this by looking for it in
/proc/kallsyms
), then you want to use a kprobe.Sometimes you also need to pay extra attention to where you hook. For example, for security use cases (i.e. blocking a syscall), syscall tracepoints (or the corresponding kernel functions, obviously) are not always the best hooking points because they might leave you open to TOCTOU attacks. LSM hooks could be a good solution for that use case.