Multi program use ftrace to hook same kernel function in same machine

138 Views Asked by At

I read this article and learn how to hook a linux kernel function by using ftrace.

int fh_install_hook(struct ftrace_hook *hook)
{
        err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
        if (err) {
                pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
                return err;
        }
 
        err = register_ftrace_function(&hook->ops);
        if (err) {
                pr_debug("register_ftrace_function() failed: %d\n", err);
 
                /* Don’t forget to turn off ftrace in case of an error. */
                ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
 
                return err;
        }
 
        return 0;
}

In one machine, It is possible to multi program use this aproach to hook same linux kernel function? I test hook sys_execve but I get register_ftrace_function return -16 if other program already hook sys_execve.

1

There are 1 best solutions below

0
divyang4481 On

return code -16 typically corresponds to EBUSY, so try to handle race conditions and conflicts. Here is one possible solution

#include <linux/ftrace.h>
#include <linux/semaphore.h>

struct ftrace_hook {
    // ... Define necessary fields for the hook
};

static DEFINE_MUTEX(hook_mutex); // Mutex for synchronization

int fh_install_hook(struct ftrace_hook *hook) {
    int err;

    mutex_lock(&hook_mutex); // Acquire mutex to synchronize

    err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
    if (err) {
        pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
        goto unlock;
    }

    err = register_ftrace_function(&hook->ops);
    if (err) {
        pr_debug("register_ftrace_function() failed: %d\n", err);
        ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
        goto unlock;
    }

unlock:
    mutex_unlock(&hook_mutex); // Release mutex
    return err;
}

void fh_remove_hook(struct ftrace_hook *hook) {
    // ... Similar to fh_install_hook, but unregister_ftrace_function
}

static int replacement_function(void) {
    // ... Custom tracing logic
    return 0;
}

int init_module(void) {
    struct ftrace_hook my_hook = {
        // ... Initialize the hook structure with appropriate values
        .ops = {
            .func = replacement_function,
            .flags = FTRACE_OPS_FL_SAVE_REGS,
        }
    };

    return fh_install_hook(&my_hook);
}

void cleanup_module(void) {
    struct ftrace_hook my_hook = {
        // ... Initialize the hook structure with appropriate values
        .ops = {
            .func = replacement_function,
            .flags = FTRACE_OPS_FL_SAVE_REGS,
        }
    };

    fh_remove_hook(&my_hook);
}