1

我对 BPF 开发领域非常陌生,需要在我的 BPF 程序中使用 kprobes,以便我可以正确检测和收集尝试通过网络发送数据包的进程的 PID。我想用我的用户空间应用程序部署这个 BPF 程序,我的用户空间应用程序在各种 linux 版本和发行版上运行——尽管都是相对较新的。

我知道 kprobe 机制并不是官方稳定的,但是我的程序在实践中出现故障的可能性有多大?我正在挂钩tcp_connectip4_datagram_connect. 我原以为这些功能在内核版本之间不会有太大变化,所以或多或少地依赖它们应该是安全的吗?还是我有什么误解?

我能否发布一个依赖于这些特定 (tcp/udp) kprobes 的应用程序,而不必过多担心兼容性或稳定性?

4

2 回答 2

2

答案实际上取决于您要跟踪的功能,并且无法确定。自 Linux 2.x 以来,该函数的原型可能根本没有改变,并在下一个版本中消失。

在实践中,我发现,例如,使用 kprobes 跟踪的函数bcc非常稳定。只有少数 bcc 工具需要更改才能处理自创建以来发布的新内核版本。这也是因为工具编写者谨慎地使用了不太可能改变的更多“中心”功能。

快速浏览一下,我会认为您引用的两个函数 ,tcp_connectip4_datagram_connect, 是这样的“中心”函数。一方面,它们都在符号表中导出。

于 2020-05-20T06:33:19.903 回答
1

对 pchaigno 的回答的补充: bcc 对于可移植性也很有效,因为 BPF 程序是在 bcc 的运行时编译的,就在被加载到内核之前(所以你一定要使用当前运行内核的函数定义)。

要在没有 bcc 的情况下工作,但在跟踪程序的可移植性方面具有相同的保证,我建议查看这篇博客文章中详细描述的 CO-RE 机制(编译一次、运行各处) 。CO-RE 特别要求内核已使用 BTF 调试信息构建。加载程序时使用此信息,以确保它与内核正确连接。

CO-RE 并不能完全消除内核更改破坏 BPF kprobes 的风险,但可以解决函数或结构定义中的一些更改。

于 2020-05-20T08:59:05.440 回答