c-如何从函数ebpf中读取所有参数

  • 本文关键字:读取 参数 ebpf 函数 c ebpf
  • 更新时间 :
  • 英文 :


所以我有这些宏

#define PT_REGS_PARM1(x) ((x)->di)
#define PT_REGS_PARM2(x) ((x)->si)
#define PT_REGS_PARM3(x) ((x)->dx)
#define PT_REGS_PARM4(x) ((x)->cx)
#define PT_REGS_PARM5(x) ((x)->r8)
#define PT_REGS_RET(x) ((x)->sp)
#define PT_REGS_FP(x) ((x)->bp)
#define PT_REGS_RC(x) ((x)->ax)
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->ip)

但上面并没有说明如何从函数中获取特定的参数,比如`__sys_write

将sys_write视为

long sys_write(unsigned int fd, const char __user *buf,
size_t count);

所以我需要缓冲区,我一直在尝试不同的宏,但不确定哪一个给了我什么?

所以有人能澄清一下吗

如果我正在读取缓冲区,那么也需要计数,这样我的ebpf程序就可以加载,不会出现越界访问错误。有人能告诉吗

使用PT_REGS_PARM*(x)

PT_REGS_PARM1(x)中的PARM代表"参数"。这些宏允许您访问kprobe或跟踪点所挂接的函数的参数。因此,例如,PT_REGS_PARM1(ctx),其中ctx是作为参数传递给eBPF程序的struct pt_regs *ctx上下文,将允许您访问第一个参数(即文件描述符fd(。类似地,PT_REGS_PARM3(ctx)将为您提供count,您可以通过查看此内核示例(write_size(来确认这一点。

。。。但是使用bpf_probe_read_*()来保持内核内存的安全

类似地,您可以使用PT_REGS_PARM2(ctx)指向缓冲区buf。然而,这是一个指针;如果您想操作这个缓冲区中包含的数据,您需要另一个步骤,否则内核可能会以不安全为由拒绝您的程序。要从这个缓冲区读取和复制部分或全部数据,您应该使用eBPF助手bpf_probe_read_*(void *dst, u32 size, const void *unsafe_ptr)之一(请参阅相关文档(。在您的情况下,该缓冲区中包含的数据来自用户空间,因此您需要bpf_probe_read_user()

关于CO-RE的说明

这并不适用于您的示例,因为您的指针只是一个缓冲区。但是,如果其中一个参数是指向结构的指针,则需要类似的预防措施来取消引用它并访问它的字段。

在这种情况下,您可能希望利用CO-RE,以确保在读取字段时访问正确的偏移量。如果您有CO-RE支持,libbpf还提供了eBPF助手周围的bpf_core_read*()包装器,这使得访问是可重定位的。有关更多信息,请参阅BPF CO-RE参考指南。

还有CO-RE(从技术上讲,这次只是BTF(,某些类型的跟踪程序,特别是BPF_PROG_TYPE_TRACING,允许您在没有任何助手的情况下访问结构字段(请参阅CO-RE的最初文章(。

相关内容

  • 没有找到相关文章

最新更新