使用Ftrace钩子arm64内核函数却导致死循环

问题描述 投票:0回答:1

我正在尝试在arm64 linux5.7中挂钩一些内核函数,例如kmem_cache_alloc(这个版本在arm64中有CONFIG_DYNAMIC_FTRACE_WITH_REGS)。但我在调用函数时总是进入无限循环。

所以我简化了代码并编写了一个演示来挂钩下面的 _do_fork,在 x86-64 上代码很好并且应该停止循环的部分工作正常。一个小细节是 ftrace_set_filter_ip 在arm64中不起作用,但 ftrace_set_filter 工作得很好。

asmlinkage long (*original_do_fork)(unsigned long clone_flags,...);

asmlinkage long hooked_do_fork(unsigned long clone_flags, unsigned long stack_start,
                               unsigned long stack_size, int __user *parent_tidptr,
                               int __user *child_tidptr, unsigned long tls) {
    printk("hooked_do_fork called!\n");
    return original_do_fork(clone_flags, stack_start, stack_size, parent_tidptr, child_tidptr, tls);
}

// fh_ftrace_thunk
static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
                                    struct ftrace_ops *ops, struct pt_regs *regs) {
    printk("fh_ftrace_thunk called!\n");
    struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

    //this should stop infinite loop but not working
    if (!within_module(parent_ip, THIS_MODULE)) regs->pc = (unsigned long)hook->function;
}

static int __init fh_init(void) {
    hook.address = kallsyms_lookup_name(hook.name);
    *((unsigned long*)&original_do_fork) = hook.address+ MCOUNT_INSN_SIZE;
    hook.ops.func = fh_ftrace_thunk;
    hook.ops.flags =  FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED | FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_IPMODIFY;
    
    err = ftrace_set_filter(&hook.ops, hook.name, strlen(hook.name), 0);
   
    err = register_ftrace_function(&hook.ops);
    return 0;
}

输出如下:

[   26.788937] fh_ftrace_thunk called!
[   26.789224] fh_ftrace_thunk called!
[   26.789544] fh_ftrace_thunk called!
[   26.789788] fh_ftrace_thunk called!
[   26.790090] fh_ftrace_thunk called!
[   26.790314] fh_ftrace_thunk called!
[   26.790600] fh_ftrace_thunk called!
[   26.790866] fh_ftrace_thunk called!
[   26.791429] fh_ftrace_thunk called!
[   26.791661] fh_ftrace_thunk called!
[   26.800664] fh_ftrace_thunk called!
[   26.801035] fh_ftrace_thunk called!
[   26.801426] fh_ftrace_thunk called!

是什么导致了这个无限循环?我是否遗漏了任何 arm64 详细信息?

linux arm hook arm64 ftrace
1个回答
0
投票

通过删除

printk("fh_ftrace_thunk called!\n");
.

并改变

*((unsigned long*)&original_do_fork) = hook.address+MCOUNT_INSN_SIZE;

*((unsigned long*)&original_do_fork) = hook.address;

我解决了上面的问题,但仍然不知道这是如何工作的。

© www.soinside.com 2019 - 2024. All rights reserved.