type
status
date
slug
summary
tags
category
icon
password
AI 摘要
这是一个简单的 eBPF 程序,用于跟踪静态检查点 openat 函数。该程序通过利用 eBPF 的 tracepoint 功能,捕获内核中的 sys_enter_openat 事件,这是每次执行 openat 系统调用时触发的事件。通过这个程序,我们可以实时监控文件打开的操作,并且记录与每个 openat 调用相关的进程信息及其打开的文件路径。
 
此程序初看第一眼可能没事问题,使用bpf_ringbuf_reserve 函数为event预分配一个内存空间,将pid和filename写到event中,再通过bpf_ringbuf_submit 函数提交到ringbuf中。
但是我们执行一下就会发现错误:“invalid mem access 'ringbuf_mem_or_null’”
notion image
问题的根源在于 bpf_ringbuf_reserve 函数的行为。该函数的主要作用是为事件预分配一块内存空间,但需要注意的是,预分配可能会失败。如果分配失败,bpf_ringbuf_reserve 会返回 NULL 指针。然而,在程序中,我们并没有对这种分配失败的情况进行处理,而是直接尝试访问返回的指针(例如写入 e->pid 和 e->filename),这就会导致潜在的空指针解引用问题。
eBPF 验证器在加载程序时会对内存访问进行严格的静态检查。当它检测到可能的非法内存访问(如对 NULL 指针的解引用)时,会拒绝加载程序,并返回上述错误。
那么我们在bpf_ringbuf_reserve函数之后再添加一层判断即可:
 
接着执行又会发现下一个错误:invalid argument: Unreleased reference id=3 alloc_insn=8
notion image
如果第一个错误我还能通过字面意思去考虑考虑,那这个错误真的就毫无头绪了,还是直接问AI吧。
notion image
它这么一说好像是有那么一点道理,将bpf_ringbuf_discard 函数加上,果然程序就能跑了。