Commit 96fed8ac authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)

kprobes: treewide: Remove trampoline_address from kretprobe_trampoline_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@devnote2Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Tested-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent f2ec8d9a
...@@ -381,7 +381,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, ...@@ -381,7 +381,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
static int __kprobes trampoline_probe_handler(struct kprobe *p, static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs) 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 /* By returning a non zero value, we are telling the kprobe handler
* that we don't want the post_handler to run * that we don't want the post_handler to run
......
...@@ -392,8 +392,7 @@ void __naked __kprobes kretprobe_trampoline(void) ...@@ -392,8 +392,7 @@ void __naked __kprobes kretprobe_trampoline(void)
/* Called from kretprobe_trampoline */ /* Called from kretprobe_trampoline */
static __used __kprobes void *trampoline_handler(struct pt_regs *regs) static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
{ {
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp);
(void *)regs->ARM_fp);
} }
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
......
...@@ -401,8 +401,7 @@ int __init arch_populate_kprobe_blacklist(void) ...@@ -401,8 +401,7 @@ int __init arch_populate_kprobe_blacklist(void)
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
{ {
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, return (void *)kretprobe_trampoline_handler(regs, (void *)kernel_stack_pointer(regs));
(void *)kernel_stack_pointer(regs));
} }
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
......
...@@ -386,7 +386,7 @@ int __init arch_populate_kprobe_blacklist(void) ...@@ -386,7 +386,7 @@ int __init arch_populate_kprobe_blacklist(void)
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 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, void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
......
...@@ -392,14 +392,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p, ...@@ -392,14 +392,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p,
__this_cpu_write(current_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) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{ {
regs->cr_iip = __kretprobe_trampoline_handler(regs, regs->cr_iip = __kretprobe_trampoline_handler(regs, NULL);
dereference_function_descriptor(kretprobe_trampoline), NULL);
/* /*
* By returning a non-zero value, we are telling * By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler * kprobe_handler() that we don't want the post_handler
......
...@@ -485,8 +485,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, ...@@ -485,8 +485,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
static int __kprobes trampoline_probe_handler(struct kprobe *p, static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs) struct pt_regs *regs)
{ {
instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, NULL);
kretprobe_trampoline, NULL);
/* /*
* By returning a non-zero value, we are telling * By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler * kprobe_handler() that we don't want the post_handler
......
...@@ -175,7 +175,7 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs) ...@@ -175,7 +175,7 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
return 1; return 1;
} }
static inline void kretprobe_trampoline(void) void kretprobe_trampoline(void)
{ {
asm volatile("nop"); asm volatile("nop");
asm volatile("nop"); asm volatile("nop");
...@@ -193,7 +193,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, ...@@ -193,7 +193,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
{ {
unsigned long orig_ret_address; 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); instruction_pointer_set(regs, orig_ret_address);
return 1; return 1;
......
...@@ -417,7 +417,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -417,7 +417,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{ {
unsigned long orig_ret_address; 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: * We get here through one of two paths:
* 1. by taking a trap -> kprobe_handler() -> here * 1. by taking a trap -> kprobe_handler() -> here
......
...@@ -347,7 +347,7 @@ int __init arch_populate_kprobe_blacklist(void) ...@@ -347,7 +347,7 @@ int __init arch_populate_kprobe_blacklist(void)
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 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, void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
......
...@@ -343,7 +343,7 @@ static void __used kretprobe_trampoline_holder(void) ...@@ -343,7 +343,7 @@ static void __used kretprobe_trampoline_holder(void)
*/ */
static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 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 * By returning a non-zero value, we are telling
* kprobe_handler() that we don't want the post_handler * kprobe_handler() that we don't want the post_handler
......
...@@ -303,7 +303,7 @@ static void __used kretprobe_trampoline_holder(void) ...@@ -303,7 +303,7 @@ static void __used kretprobe_trampoline_holder(void)
*/ */
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 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; return 1;
} }
......
...@@ -451,7 +451,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, ...@@ -451,7 +451,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
{ {
unsigned long orig_ret_address = 0; 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->tpc = orig_ret_address;
regs->tnpc = orig_ret_address + 4; regs->tnpc = orig_ret_address + 4;
......
...@@ -49,7 +49,6 @@ extern __visible kprobe_opcode_t optprobe_template_end[]; ...@@ -49,7 +49,6 @@ extern __visible kprobe_opcode_t optprobe_template_end[];
extern const int kretprobe_blacklist_size; extern const int kretprobe_blacklist_size;
void arch_remove_kprobe(struct kprobe *p); void arch_remove_kprobe(struct kprobe *p);
asmlinkage void kretprobe_trampoline(void);
extern void arch_kprobe_override_function(struct pt_regs *regs); extern void arch_kprobe_override_function(struct pt_regs *regs);
......
...@@ -1064,7 +1064,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs) ...@@ -1064,7 +1064,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs)
regs->ip = (unsigned long)&kretprobe_trampoline; regs->ip = (unsigned long)&kretprobe_trampoline;
regs->orig_ax = ~0UL; 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); NOKPROBE_SYMBOL(trampoline_handler);
......
...@@ -188,14 +188,22 @@ extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, ...@@ -188,14 +188,22 @@ extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs); struct pt_regs *regs);
extern int arch_trampoline_kprobe(struct kprobe *p); 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 */ /* If the trampoline handler called from a kprobe, use this version */
unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer); void *frame_pointer);
static nokprobe_inline static nokprobe_inline
unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, unsigned long kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer) void *frame_pointer)
{ {
unsigned long ret; unsigned long ret;
...@@ -205,7 +213,7 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, ...@@ -205,7 +213,7 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs,
* be running at this point. * be running at this point.
*/ */
kprobe_busy_begin(); kprobe_busy_begin();
ret = __kretprobe_trampoline_handler(regs, trampoline_address, frame_pointer); ret = __kretprobe_trampoline_handler(regs, frame_pointer);
kprobe_busy_end(); kprobe_busy_end();
return ret; return ret;
......
...@@ -1864,7 +1864,6 @@ static struct notifier_block kprobe_exceptions_nb = { ...@@ -1864,7 +1864,6 @@ static struct notifier_block kprobe_exceptions_nb = {
#ifdef CONFIG_KRETPROBES #ifdef CONFIG_KRETPROBES
unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
void *trampoline_address,
void *frame_pointer) void *frame_pointer)
{ {
kprobe_opcode_t *correct_ret_addr = NULL; kprobe_opcode_t *correct_ret_addr = NULL;
...@@ -1879,7 +1878,7 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, ...@@ -1879,7 +1878,7 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
BUG_ON(ri->fp != frame_pointer); 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; correct_ret_addr = ri->ret_addr;
/* /*
* This is the real return address. Any other * This is the real return address. Any other
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment