Skip to content

kprobes incompatibility #47

@jpoimboe

Description

@jpoimboe

When kprobes registers with ftrace before kpatch does for the same function, kprobes "wins", until the kprobe has been unregistered with ftrace. The kernel kprobe_ftrace_handler function changes regs->ip, which overwrites the value which kpatch had written.

Option 1:

diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
index 23ef5c5..5969176 100644
--- a/arch/x86/kernel/kprobes/ftrace.c
+++ b/arch/x86/kernel/kprobes/ftrace.c
@@ -57,6 +57,7 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
    struct kprobe *p;
    struct kprobe_ctlblk *kcb;
    unsigned long flags;
+   unsigned long save_ip = regs->ip;

    /* Disable irq for emulating a breakpoint and avoiding preempt */
    local_irq_save(flags);
@@ -80,6 +81,8 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
         * If pre_handler returns !0, it sets regs->ip and
         * resets current kprobe.
         */
+       if (ip != save_ip)
+           regs->ip = save_ip;
    }
 end:
    local_irq_restore(flags);

With this patch, if both kpatch and a kprobe handler try to modify the IP, kpatch always wins.

Option 2:

Create an FTRACE_OPS_FL_LAST flag which ensures that kpatch is called last, so that any kprobes attempts to update regs->ip will be ignored.

This is another variation on option 1: if both kpatch and a kprobe handler try to modify the IP, kpatch always wins.

Option 3:

Create an FTRACE_OPS_FL_FIRST flag which ensures that kpatch is called first. Then pass the updated regs->ip to the kprobes functions so they can set their breakpoint at the beginning of the replacement function. The downside here is that kprobes modules can override kpatch's redirecting of functions, but that may not be much of an issue.

So if both kpatch and a kprobe handler try to modify the IP, kprobes wins.

Option 4:

Create an FTRACE_OPS_FL_IPMODIFY flag: first to register wins.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions