【问题标题】:How to print the file path from an open syscall using ebpf python?如何使用 ebpf python 从打开的系统调用中打印文件路径?
【发布时间】:2020-03-01 22:42:59
【问题描述】:

我使用来自 python bcc 模块的 bpf,并且我希望我的探测函数将打印当前文件的文件路径(一种自定义的简化 opensnoop)。 我该怎么做?

这是我目前所拥有的:

b = BPF(text="""
#include <linux/ptrace.h>      
#include<linux/sched.h>

BPF_HASH(last);      

int trace_entry(struct pt_regs *ctx)      
{
    char fileName[200] = {0};
    bpf_probe_read(fileName, sizeof(fileName), &PT_REGS_PARM1(ctx));  
    bpf_trace_printk("File Opened<%s>\\n", fileName);      
    return 0;
}
""")

print("Tracing for open... Ctrl-C to end")
b.attach_kprobe(event="do_sys_open", fn_name="trace_entry")
#b.attach_kprobe(event=b.get_syscall_fnname("open"), fn_name='funcky')
b.trace_print()

【问题讨论】:

  • 你试过什么?请阅读 bcc 的文档和/或尝试从现有的 opensnoop 派生您的程序,这听起来不应该有任何特别的缺陷。
  • 我已经编辑了我到目前为止所做的事情。由于某种原因,它不能按预期工作-我得到“文件打开”而没有文件路径。
  • 我的猜测是bpf_probe_read() 调用失败是因为您尝试读取太多数据(200 字节,但文件名可能不会那么长),这看起来不安全!来自 bcc 的 opensnoop 示例有一种方法可以检索文件名的长度,并且只读取必要的内容。或者,我认为您可以尝试用bpf_probe_read_user_str() 替换该调用,这样您就不必关心文件名的实际长度。
  • (我忘了提到 bpf_probe_read_user_str() 仅在最近的内核中可用,从 5.5 开始。在较旧的内核上,现在已弃用的 bpf_probe_read_str() 可用。请参阅 rationale。)

标签: python linux ebpf bcc-bpf


【解决方案1】:

简单:
将其插入内核代码:

// Nicer way to call bpf_trace_printk()
#define bpf_custom_printk(fmt, ...)                     \
        ({                                              \
            char ____fmt[] = fmt;                       \
            bpf_trace_printk(____fmt, sizeof(____fmt),  \
                    ##__VA_ARGS__);                     \
        })
struct pair {
    uint32_t lip; // local IP
    uint32_t rip; // remote IP
};

并在内核代码中插入打印输出代码。此函数调用与 printf 完全一样,具有所有格式和占位符...

bpf_custom_printk("This year is %d\n", 2020);

打印输出:

sudo cat /sys/kernel/debug/tracing/trace_pipe

【讨论】:

  • 我想我已经找到了一种不改变内核代码的方法。我会确保它正常工作并更新帖子。
  • @Liroshka 你的最终解决方案是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2014-06-24
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多