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@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Tested-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
f2ec8d9a3b
commit
96fed8ac2b
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, ®s->sp);
|
||||
return (void *)kretprobe_trampoline_handler(regs, ®s->sp);
|
||||
}
|
||||
NOKPROBE_SYMBOL(trampoline_handler);
|
||||
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue