0

I tried to probe a simple function (e.g. myfunc) which I added in the kernel as following:

  1. I created a file (myfile.c) under ~/source/kernel/ i.e. ~/source/kernel/myfile.c
  2. I added a simple system call mysyscall and a local function myfunc in this file. mysyscall function calls myfunc function.

I can get the address of the function using

cat /proc/kallsyms | grep myfunc

But the kprobe handler doesn't get called when I call the myfunc.

I can probe the system call 'mysyscall'. But when I try to probe 'myfunc', the handler doesn't get called.

Can anyone please explain why this is the behavior? Thanks.

As asked by Eugene, below is the code for kprobe and, mysyscall & myfunc. The kprobe handler doesn't get called in the following code. But if i uncomment Line B and comment A in kprobe code given below, then kprobe handler gets called.

I used kernel version 4.8. I added ~/source/kernel/myfile.c to write mysyscall and myfunc as given below:

#include <linux/linkage.h>
#include <linux/export.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <linux/printk.h>
#include <linux/slab.h>

extern int myfunc(int ax)
{
        int x = 6;

        return x;
}
asmlinkage int* sys_mysyscall(int bx){
        int *retval;
        int ret = 0;
        printk(KERN_ALERT "Hello World!\n");
        ret =  myfunc(10);

        retval = kmalloc(sizeof(int), GFP_KERNEL);
        *retval = 55;
        printk("sum: %d\n", *retval);


        printk("myfunc return value: %d\n", ret);

    return retval;
}
EXPORT_SYMBOL(sys_mysyscall);

kprobe module code is as below:

#include<linux/module.h>
#include<linux/version.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/kprobes.h>

//Line A
static const char *probed_func = "myfunc";

//Line B
//static const char *probed_func = "sys_mysyscall";


static unsigned int counter = 0;

int Pre_Handler(struct kprobe *p, struct pt_regs *regs){
    printk("Pre_Handler: counter=%u\n",counter++);
    return 0;
}

void Post_Handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags){
    printk("Post_Handler: counter=%u\n",counter++);
}

static struct kprobe kp;

int myinit(void)
{
    int error;
    printk("module inserted\n ");
    kp.pre_handler = Pre_Handler;
    kp.post_handler = Post_Handler;
    kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name(probed_func);
    error = register_kprobe(&kp);
    if(error)
    {
        pr_err("can't register_kprobe :(\n");
        return error;
    }
    else
    {
        printk("probe registration successful\n");
    }
    return 0;
}

void myexit(void)
{
    unregister_kprobe(&kp);
    printk("module removed\n ");
}

module_init(myinit);
module_exit(myexit);
MODULE_AUTHOR("psin");
MODULE_DESCRIPTION("KPROBE MODULE");
MODULE_LICENSE("GPL");

I use a kernel module to call mysyscall as below:

sys_mysyscall(12);//12 is some random integer as parameter
psin
  • 59
  • 8
  • Please describe how exactly you placed the Kprobe on "myfunc". If you did it from the code of a kernel module, please show that code or add a link to it to the question. – Eugene May 16 '17 at 08:15
  • One more thing. Did you check if registration of the Kprobe succeed? If you use `register_kprobe()` and it fails, the return value may give a hint on what has gone wrong. – Eugene May 16 '17 at 08:19
  • Most probably your function, disregarding weird definition, is just inlined by compiler. – 0andriy May 22 '17 at 21:15
  • any updates/solutions to this issue? I am also facing similar issue right now. Any input on this would be helpful. – cooshal May 09 '18 at 15:36
  • 1
    @Cooshal I have answered my own question [here] (https://stackoverflow.com/questions/49480167/kprobe-not-working-for-some-functions). You need to make sure the target kernel function is not inline, and also you are referring to the correct kernel after compilation :) Also export the function using EXPORT_SYMBOL_GPL just to make sure the symbol exists for probing. Hope that helps. – psin May 19 '18 at 19:49
  • @psin: thanks ! I had similar problems but later I figured it out that it should not be inline. And, I guess in Linux kernel you simply need to use `noinline` as `__attribute__((noinline))` resulted in compilation error. – cooshal May 25 '18 at 11:42

0 Answers0