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

拦截Linux系统调用时无法printk输出用户空间字符串参数的问题

问题根源

你遇到的-14错误对应内核标准错误码EFAULT,表示传入的用户空间地址filename不合法:要么地址不属于当前进程的用户空间映射范围,要么没有可读权限。

解决方案

不要手动调用strncpy_from_user/copy_from_user处理文件名,直接使用内核原生专门用于读取用户空间文件路径的getname接口,该接口会自动完成地址合法性校验、缺页处理、内存分配等逻辑,用完调用putname释放内存即可,修改后的代码如下:

static inline long hacked_open(const char __user *filename, int flags, umode_t mode)
{
    const char *kname = getname(filename);
    if (!IS_ERR(kname)) {
        printk("%s\n", kname);
        putname(kname);
    } else {
        printk("---err len : %ld ---\n", PTR_ERR(kname));
    }

    orig_func a = (orig_func)orig_open;
    return a(filename, flags, mode);
}

额外排查项

如果修改后仍然大量出现EFAULT错误,需要检查你的Hook逻辑是否符合以下要求:

  • 确保你拿到的filename参数是正确的:64位Linux系统调用通过寄存器传参,如果你使用kprobe/ftrace等方式Hook,要确认参数提取逻辑没有拿错寄存器值
  • 确保Hook逻辑是在触发open系统调用的进程上下文中执行,不能在中断上下文、其他进程上下文访问当前进程的用户空间地址
  • 确认内核版本适配:5.x以上内核的access_ok接口删除了第一个参数,如果你手动校验地址要注意接口适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 06:24:04