Linux Kernel - How to match jprobe with kretprobe?

I am writing a kernel module to monitor several system calls that want to return function arguments to the user (via a network socket) if the call was successful.

jprobe.kp.symbol_name = "rename"; jprobe.entry = rename_handler; kretprobe.kp.symbol_name = "rename"; kretprobe.handler = rename_ret_handler; static rename_obj_t _g_cur_rename = NULL; static void _rename_handler(const char *oldpath, const char *newpath) { _g_cur_rename = create_rename(oldpath, newpath); jprobe_return(); } static void _rename_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { /* Send only if successful */ if (regs_return_value(regs) == 0) { add_send_queue(_g_cur_rename); } return 0; } 

I am worried that another rename syscall might preempt [1] the current one after jprobe, and I will send the wrong return codes and arguments.

 jprobe: rename(a, b) jprobe rename(c, d) kretprobe kretprobe 

Edit: This article [2] states that interrupts are disabled during the kprobe handler. But does this mean that interrupts are disabled in the whole chain (jprobe β†’ kprobe β†’ kretprobe) or just for that one kprobe?

+8
c linux linux-kernel kernel kernel-module
source share
1 answer

Interrupts are disabled for every jprobe call: not for the entire sequence.

How many calls do you expect when the application processes them? There are different approaches depending on how fast you expect calls to come. The simplest method, if you expect maybe a few hundred calls before you can process them and you dedicate static memory to the goal, is to implement a static array of rename_obj_t objects in memory, and then use atomic_add from the asm kernel to point to next entry (resize your array).

This way you return a unique static reference every time until the counter wraps before processing the return values. atomic_add guaranteed to have the right memory barriers, so you don’t have to worry about things like cache consistency.

+1
source share

All Articles