Skip to content

Commit

Permalink
kprobes: treewide: Remove trampoline_address from kretprobe_trampolin…
Browse files Browse the repository at this point in the history
…e_handler()

The __kretprobe_trampoline_handler() callback, called from low level
arch kprobes methods, has the 'trampoline_address' parameter, which is
entirely superfluous as it basically just replicates:

  dereference_kernel_function_descriptor(kretprobe_trampoline)

In fact we had bugs in arch code where it wasn't replicated correctly.

So remove this superfluous parameter and use kretprobe_trampoline_addr()
instead.

Link: https://lkml.kernel.org/r/163163044546.489837.13505751885476015002.stgit@devnote2

Signed-off-by: Masami Hiramatsu <[email protected]>
Tested-by: Andrii Nakryiko <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
  • Loading branch information
mhiramat authored and rostedt committed Oct 1, 2021
1 parent f2ec8d9 commit 96fed8a
Show file tree
Hide file tree
Showing 16 changed files with 29 additions and 27 deletions.
2 changes: 1 addition & 1 deletion arch/arc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs)
{
regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
regs->ret = __kretprobe_trampoline_handler(regs, NULL);

/* By returning a non zero value, we are telling the kprobe handler
* that we don't want the post_handler to run
Expand Down
3 changes: 1 addition & 2 deletions arch/arm/probes/kprobes/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ void __naked __kprobes kretprobe_trampoline(void)
/* Called from kretprobe_trampoline */
static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
{
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
(void *)regs->ARM_fp);
return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp);
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
Expand Down
3 changes: 1 addition & 2 deletions arch/arm64/kernel/probes/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,7 @@ int __init arch_populate_kprobe_blacklist(void)

void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
{
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
(void *)kernel_stack_pointer(regs));
return (void *)kretprobe_trampoline_handler(regs, (void *)kernel_stack_pointer(regs));
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
Expand Down
2 changes: 1 addition & 1 deletion arch/csky/kernel/probes/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ int __init arch_populate_kprobe_blacklist(void)

void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
{
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
return (void *)kretprobe_trampoline_handler(regs, NULL);
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
Expand Down
5 changes: 2 additions & 3 deletions arch/ia64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p,
__this_cpu_write(current_kprobe, p);
}

static void kretprobe_trampoline(void)
void kretprobe_trampoline(void)
{
}

int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
regs->cr_iip = __kretprobe_trampoline_handler(regs,
dereference_function_descriptor(kretprobe_trampoline), NULL);
regs->cr_iip = __kretprobe_trampoline_handler(regs, NULL);
/*
* By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler
Expand Down
3 changes: 1 addition & 2 deletions arch/mips/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,8 +485,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs)
{
instruction_pointer(regs) = __kretprobe_trampoline_handler(regs,
kretprobe_trampoline, NULL);
instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, NULL);
/*
* By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler
Expand Down
4 changes: 2 additions & 2 deletions arch/parisc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
return 1;
}

static inline void kretprobe_trampoline(void)
void kretprobe_trampoline(void)
{
asm volatile("nop");
asm volatile("nop");
Expand All @@ -193,7 +193,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
{
unsigned long orig_ret_address;

orig_ret_address = __kretprobe_trampoline_handler(regs, trampoline_p.addr, NULL);
orig_ret_address = __kretprobe_trampoline_handler(regs, NULL);
instruction_pointer_set(regs, orig_ret_address);

return 1;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
unsigned long orig_ret_address;

orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
orig_ret_address = __kretprobe_trampoline_handler(regs, NULL);
/*
* We get here through one of two paths:
* 1. by taking a trap -> kprobe_handler() -> here
Expand Down
2 changes: 1 addition & 1 deletion arch/riscv/kernel/probes/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ int __init arch_populate_kprobe_blacklist(void)

void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
{
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
return (void *)kretprobe_trampoline_handler(regs, NULL);
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ static void __used kretprobe_trampoline_holder(void)
*/
static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
regs->psw.addr = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
regs->psw.addr = __kretprobe_trampoline_handler(regs, NULL);
/*
* By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler
Expand Down
2 changes: 1 addition & 1 deletion arch/sh/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static void __used kretprobe_trampoline_holder(void)
*/
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
regs->pc = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
regs->pc = __kretprobe_trampoline_handler(regs, NULL);

return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
{
unsigned long orig_ret_address = 0;

orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
orig_ret_address = __kretprobe_trampoline_handler(regs, NULL);
regs->tpc = orig_ret_address;
regs->tnpc = orig_ret_address + 4;

Expand Down
1 change: 0 additions & 1 deletion arch/x86/include/asm/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ extern __visible kprobe_opcode_t optprobe_template_end[];
extern const int kretprobe_blacklist_size;

void arch_remove_kprobe(struct kprobe *p);
asmlinkage void kretprobe_trampoline(void);

extern void arch_kprobe_override_function(struct pt_regs *regs);

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/kprobes/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs)
regs->ip = (unsigned long)&kretprobe_trampoline;
regs->orig_ax = ~0UL;

return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, &regs->sp);
return (void *)kretprobe_trampoline_handler(regs, &regs->sp);
}
NOKPROBE_SYMBOL(trampoline_handler);

Expand Down
18 changes: 13 additions & 5 deletions include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,23 @@ extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs);
extern int arch_trampoline_kprobe(struct kprobe *p);

void kretprobe_trampoline(void);
/*
* Since some architecture uses structured function pointer,
* use dereference_function_descriptor() to get real function address.
*/
static nokprobe_inline void *kretprobe_trampoline_addr(void)
{
return dereference_kernel_function_descriptor(kretprobe_trampoline);
}

/* If the trampoline handler called from a kprobe, use this version */
unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer);
void *frame_pointer);

static nokprobe_inline
unsigned long kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer)
void *frame_pointer)
{
unsigned long ret;
/*
Expand All @@ -205,7 +213,7 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs,
* be running at this point.
*/
kprobe_busy_begin();
ret = __kretprobe_trampoline_handler(regs, trampoline_address, frame_pointer);
ret = __kretprobe_trampoline_handler(regs, frame_pointer);
kprobe_busy_end();

return ret;
Expand Down
3 changes: 1 addition & 2 deletions kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1864,7 +1864,6 @@ static struct notifier_block kprobe_exceptions_nb = {
#ifdef CONFIG_KRETPROBES

unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer)
{
kprobe_opcode_t *correct_ret_addr = NULL;
Expand All @@ -1879,7 +1878,7 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,

BUG_ON(ri->fp != frame_pointer);

if (ri->ret_addr != trampoline_address) {
if (ri->ret_addr != kretprobe_trampoline_addr()) {
correct_ret_addr = ri->ret_addr;
/*
* This is the real return address. Any other
Expand Down

0 comments on commit 96fed8a

Please sign in to comment.