You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

挂载到getname的BPF程序调用renameat2时未触发问题排查

问题排查与解决方案

1. renameat2调用未触发getname/getname_flags的原因及排查

  • 内核实现变更:较新内核版本中,renameat2的代码逻辑可能已绕过getname封装,直接通过copy_from_user读取用户空间参数,不再依赖getname系列函数。建议直接查看当前内核linux/fs/namei.c中renameat2的实现代码,确认调用链是否包含getname。
  • 符号匹配错误:getname_flags可能存在版本后缀(如getname_flags@vmlinux),或挂载探针时符号解析失败。可执行bpftool prog show查看探针是否成功关联到正确内核符号。
  • 权限过滤逻辑限制:代码中硬编码了UID=1002,若执行mv命令的用户UID不符,会直接跳过输出。建议先注释UID过滤逻辑,测试是否有输出。

2. strncpy_from_user挂载报错的解决

  • 参数签名不匹配:strncpy_from_user的标准内核签名为long strncpy_from_user(char *dst, const char __user *src, long count),BPF程序必须严格匹配该参数列表,否则会触发EINVAL错误。
  • 内核探测限制:部分内核函数因安全或稳定性原因被禁止kprobe/fentry探测,strncpy_from_user可能属于此类。可尝试改用kretprobe,或检查内核配置中CONFIG_KPROBES、CONFIG_BPF_KPROBE_OVERRIDE是否开启。

3. 替代实现方案

  • 直接探测renameat2系统调用tracepoint:通过sched/sys_enter_renameat2和sched/sys_exit_renameat2 tracepoint直接获取系统调用参数,无需依赖内部函数调用链。示例代码:
SEC("tracepoint/syscalls/sys_enter_renameat2")
int trace_renameat2_enter(struct trace_event_raw_sys_enter *ctx) {
    uid_t uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
    if (uid != 1002) return 0;
    const char __user *oldpath = (const char __user *)ctx->args[1];
    const char __user *newpath = (const char __user *)ctx->args[3];
    char buf_old[256], buf_new[256];
    if (bpf_probe_read_user_str(buf_old, sizeof(buf_old), oldpath) > 0) {
        bpf_printk("renameat2 oldpath: %s", buf_old);
    }
    if (bpf_probe_read_user_str(buf_new, sizeof(buf_new), newpath) > 0) {
        bpf_printk("renameat2 newpath: %s", buf_new);
    }
    return 0;
}
  • 验证内核实际调用链:用perf工具查看renameat2执行时的函数栈,确认真实调用路径:
perf probe -x /usr/lib/modules/$(uname -r)/build/vmlinux renameat2
perf record -e probe:renameat2 -aR mv old.txt new.txt
perf script

内容的提问来源于stack exchange,提问作者Dennis Orlando

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:14:50