修改lseek函数参数时bpf_probe_write_user返回-14错误求助
解决bpf_probe_write_user修改lseek参数返回-14(EFAULT)的问题
问题根源
错误码-14对应EFAULT,核心原因是你用错了内存写入函数:
struct trace_event_raw_sys_enter* ctx是内核空间的结构体,ctx->args[2]是内核中暂存的用户态参数副本,属于内核地址空间bpf_probe_write_user的作用是向用户空间内存写入数据,传入内核地址必然触发地址合法性检查失败
你之前修改open的filename参数成功,是因为filename本身是用户空间指针,当时你修改的是该指针指向的用户空间内存,而非直接修改ctx->args里的指针值——这两种场景的目标地址空间完全不同。
解决方案
要修改tracepoint中sys_enter_lseek的参数,需使用针对内核空间的写入函数bpf_probe_write_kernel(内核4.18+版本支持):
修改后的代码示例:
SEC("tracepoint/syscalls/sys_enter_lseek") int sys_enter_lseek(struct trace_event_raw_sys_enter* ctx) { pid_t pid = bpf_get_current_pid_tgid() >> 32; if (pid != target_pid) return 0; int whence = 2; // 改用bpf_probe_write_kernel写入内核空间的args参数 long ret = bpf_probe_write_kernel((void*)&(ctx->args[2]), (void*)&whence, sizeof(ctx->args[2])); bpf_printk("sys_enter_lseek ret: %d", ret); return 0; }
额外注意事项
- 确保类型匹配:
lseek的whence是int类型,ctx->args成员通常为unsigned long,写入时可通过强制转换或使用同类型变量保证兼容性 - 内核配置:部分版本需开启
CONFIG_BPF_KPROBE_OVERRIDE等相关配置,确保bpf_probe_write_kernel功能可用 - 若需修改用户空间原始参数(而非tracepoint副本),需通过
bpf_get_current_task获取进程栈信息后定位参数位置,这种场景复杂度更高,一般修改tracepoint副本即可实现参数拦截效果
内容的提问来源于stack exchange,提问作者lxt
相关产品推荐
相关产品推荐

