register_kretprobe 失败,return 值为 -2

register_kretprobe fails with a return value of -2

我写了一个 kretprobe 来连接到 fs/binfmt_elf.c 文件中提到的 randomize_stack_top() 函数。在使用 insmod 加载 LKM 时,register_kretprobe() 调用失败,return 值为 -2。我该如何处理 debugging/rectifying 才能启动我的模块?

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/current.h>
#include <asm/param.h>

/* Global variables */
int randomize_stack_retval;

//  randomize_stack_top() kretprobe specific declarations 
static char stack_name[NAME_MAX] = "randomize_stack_top";

static int randomize_stack_top_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    return 0;
}

static int randomize_stack_top_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    randomize_stack_retval = regs_return_value(regs);   //store in global variable
    printk(KERN_INFO "%d\n",randomize_stack_retval);
    return 0;
}

//randomize_stack_top return probe
static struct kretprobe randomize_kretprobe = {
    .handler = randomize_stack_top_ret_handler,
    .entry_handler = randomize_stack_top_entry_handler,
    .maxactive = NR_CPUS,
};

/* Register kretprobe */
static int __init kretprobe_init(void)
{
    int ret;

    randomize_kretprobe.kp.symbol_name = stack_name;

    ret = register_kretprobe(&randomize_kretprobe);
    if (ret < 0) {
        printk(KERN_INFO "register_kretprobe failed, returned %d\n",
                ret);
        return -1;
    }
    printk(KERN_INFO "Planted return probe at %s: %p\n",
            randomize_kretprobe.kp.symbol_name, randomize_kretprobe.kp.addr);

    return 0;
}

/* Unregister kretprobe */
static void __exit kretprobe_exit(void)
{
    unregister_kretprobe(&randomize_kretprobe);
    printk(KERN_INFO "kretprobe at %p unregistered\n",
            randomize_kretprobe.kp.addr);

    //  nmissed > 0 suggests that maxactive was set too low. 
    printk(KERN_INFO "Missed probing %d instances of %s\n",
  randomize_kretprobe.nmissed, randomize_kretprobe.kp.symbol_name);

}

module_init(kretprobe_init);
module_exit(kretprobe_exit);
MODULE_LICENSE("GPL");

-2对应于-ENOENT(你可以在include/uapi/asm-generic/errno-base.h中查看)。可能,这意味着 kprobe 找不到具有给定名称的符号。

请注意,randomize_stack_top 是具有简短实现的静态函数,并且仅使用一次。所以它可以被 gcc 内联。