ARM64 Linux内核中ftrace hook函数失败的问题求助
问题描述
在ARM64架构的Linux内核(Ubuntu 22.04,内核5.15.0-43-generic)中使用ftrace hook内核函数security_path_unlink时失败,ftrace_set_filter_ip()返回错误码-22(EINVAL)。
核心代码:
static void notrace ftrace_hook_handler(size_t ip, size_t parent_ip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { pr_info("ftrace hooking"); return; } int my_ftrace_hook { struct ftrace_ops fops; fops.func = ftrace_hook_handler; fops.flags = FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED; pr_info("symbol: %s, addr: %px\n", "security_path_unlink", addr_security_path_unlink); err = ftrace_set_filter_ip(&fops, addr_security_path_unlink, 0, 0); if (err) { pr_err("ftrace_set_filter_ip() failed: %d\n", err); return err; } }
dmesg报错输出:
[ 945.791221] ftrace_module: loading out-of-tree module taints kernel. [ 945.791464] ftrace_module: module verification failed: signature and/or required key missing - tainting kernel [ 945.820649] [ftrace_module] symbol: security_path_unlink, addr: ffffa13fc4fafd10 [ 945.820663] [my_ftrace_hook] ftrace_set_filter_ip() failed: -22
系统环境信息:
# uname -a Linux ubuntu2204 5.15.0-43-generic #46-Ubuntu SMP Wed Jul 13 06:42:04 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux # cat /etc/os-release PRETTY_NAME="Ubuntu 22.04 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04 (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy
修复方案
错误码-22(EINVAL)表示参数无效,结合ARM64架构特性,可从以下几点排查修复:
修正ftrace操作流程
必须先注册ftrace_ops结构体,再设置过滤规则,原代码顺序颠倒导致参数无效。调整后的代码示例:int my_ftrace_hook(void) { struct ftrace_ops fops = {0}; int err; fops.func = ftrace_hook_handler; fops.flags = FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED; pr_info("symbol: %s, addr: %px\n", "security_path_unlink", addr_security_path_unlink); // 先注册ftrace函数 err = register_ftrace_function(&fops); if (err) { pr_err("register_ftrace_function failed: %d\n", err); return err; } // 再设置IP过滤 err = ftrace_set_filter_ip(&fops, addr_security_path_unlink, 0, 0); if (err) { pr_err("ftrace_set_filter_ip failed: %d\n", err); unregister_ftrace_function(&fops); return err; } return 0; }完整初始化ftrace_ops结构体
原代码未对fops做清零初始化,可能存在残留垃圾值导致参数异常,建议使用{0}直接初始化。验证函数地址有效性
通过cat /proc/kallsyms | grep security_path_unlink核对代码中使用的地址是否与内核符号表一致,确保符号解析逻辑正确。检查内核配置
确认内核已开启ftrace相关配置:zcat /proc/config.gz | grep -E "CONFIG_FTRACE|CONFIG_FUNCTION_TRACER|CONFIG_DYNAMIC_FTRACE"若上述配置未开启,需重新编译内核开启对应选项。
确认函数支持ftrace
检查security_path_unlink的定义是否带有notrace属性,带有该属性的函数无法被ftrace追踪。
参考开源项目
- ftrace官方示例模块:内核源码树中
samples/ftrace/目录下包含多种ftrace使用示例,覆盖基础追踪、过滤等场景。 - trace-cmd:用户空间调试工具,可用于验证内核函数是否可被ftrace追踪,辅助排查问题。
内容的提问来源于stack exchange,提问作者hdthky
相关产品推荐
相关产品推荐

