如何在eBPF程序中解引用指针?hook文件删除遇编译报错求助
eBPF程序解引用filename指针编译报错的解决方法
问题描述
编写了一个hookdo_unlinkat跟踪文件删除的eBPF程序,程序其余部分运行正常,但尝试直接解引用从struct filename获取的filename指针时出现编译错误,而bpf_printk可以正常输出该指针指向的内容。
原始代码
#define __TARGET_ARCH_arm64 #include <linux/ptrace.h> #include <bpf/bpf_tracing.h> #include <bpf/bpf_core_read.h> char LICENSE[] SEC("license") = "Dual BSD/GPL"; typedef struct { int counter; } atomic_t; struct filename { const char *name; const char *uptr; atomic_t refcnt; struct audit_names *aname; const char iname[0]; }; SEC("kprobe/do_unlinkat") int BPF_KPROBE(do_unlinkat, int dfd, struct filename *name) { const char *filename = BPF_CORE_READ(name, name); // 此行导致报错 if (filename!=NULL && *filename=='t') return 1; bpf_printk("Deleting this file:%s", filename); return 0; }
错误信息
arg#0 reference type('FWD pt_regs') size cannot be determined: -22 0: R1=ctx() R10=fp0 ; int BPF_KPROBE(do_unlinkat, int dfd, struct filename *name) @ test_ebpf.c:30 ... R3 invalid mem access 'scalar' processed 11 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
原因及解决方法
报错核心原因是:filename指向用户空间内存,eBPF验证器禁止直接解引用用户空间指针,必须通过内核提供的安全读取函数来访问。bpf_printk能正常工作是因为它内部已经封装了用户空间指针的安全读取逻辑。
修改代码,使用bpf_core_read_user安全读取指针指向的内容:
#define __TARGET_ARCH_arm64 #include <linux/ptrace.h> #include <bpf/bpf_tracing.h> #include <bpf/bpf_core_read.h> char LICENSE[] SEC("license") = "Dual BSD/GPL"; typedef struct { int counter; } atomic_t; struct filename { const char *name; const char *uptr; atomic_t refcnt; struct audit_names *aname; const char iname[0]; }; SEC("kprobe/do_unlinkat") int BPF_KPROBE(do_unlinkat, int dfd, struct filename *name) { const char *filename = BPF_CORE_READ(name, name); char first_char = 0; if (filename != NULL) { // 使用bpf_core_read_user安全读取用户空间的第一个字符 bpf_core_read_user(&first_char, sizeof(first_char), filename); if (first_char == 't') { return 1; } } bpf_printk("Deleting this file:%s", filename); return 0; }
关键说明
bpf_core_read_user是libbpf提供的封装函数,会自动处理指针合法性检查,避免触发eBPF验证器的内存访问错误。- 如果需要读取更长的字符串片段,可以扩展缓冲区大小,一次性读取更多字节,但需注意内存边界,防止越界访问。
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

