Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Masami Hiramatsu and committed by
Steven Rostedt (VMware)
96fed8ac f2ec8d9a

+29 -27
+1 -1
arch/arc/kernel/kprobes.c
··· 381 381 static int __kprobes trampoline_probe_handler(struct kprobe *p, 382 382 struct pt_regs *regs) 383 383 { 384 - regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 384 + regs->ret = __kretprobe_trampoline_handler(regs, NULL); 385 385 386 386 /* By returning a non zero value, we are telling the kprobe handler 387 387 * that we don't want the post_handler to run
+1 -2
arch/arm/probes/kprobes/core.c
··· 392 392 /* Called from kretprobe_trampoline */ 393 393 static __used __kprobes void *trampoline_handler(struct pt_regs *regs) 394 394 { 395 - return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, 396 - (void *)regs->ARM_fp); 395 + return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp); 397 396 } 398 397 399 398 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+1 -2
arch/arm64/kernel/probes/kprobes.c
··· 401 401 402 402 void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 403 403 { 404 - return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, 405 - (void *)kernel_stack_pointer(regs)); 404 + return (void *)kretprobe_trampoline_handler(regs, (void *)kernel_stack_pointer(regs)); 406 405 } 407 406 408 407 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+1 -1
arch/csky/kernel/probes/kprobes.c
··· 386 386 387 387 void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 388 388 { 389 - return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 389 + return (void *)kretprobe_trampoline_handler(regs, NULL); 390 390 } 391 391 392 392 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+2 -3
arch/ia64/kernel/kprobes.c
··· 392 392 __this_cpu_write(current_kprobe, p); 393 393 } 394 394 395 - static void kretprobe_trampoline(void) 395 + void kretprobe_trampoline(void) 396 396 { 397 397 } 398 398 399 399 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 400 400 { 401 - regs->cr_iip = __kretprobe_trampoline_handler(regs, 402 - dereference_function_descriptor(kretprobe_trampoline), NULL); 401 + regs->cr_iip = __kretprobe_trampoline_handler(regs, NULL); 403 402 /* 404 403 * By returning a non-zero value, we are telling 405 404 * kprobe_handler() that we don't want the post_handler
+1 -2
arch/mips/kernel/kprobes.c
··· 485 485 static int __kprobes trampoline_probe_handler(struct kprobe *p, 486 486 struct pt_regs *regs) 487 487 { 488 - instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, 489 - kretprobe_trampoline, NULL); 488 + instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, NULL); 490 489 /* 491 490 * By returning a non-zero value, we are telling 492 491 * kprobe_handler() that we don't want the post_handler
+2 -2
arch/parisc/kernel/kprobes.c
··· 175 175 return 1; 176 176 } 177 177 178 - static inline void kretprobe_trampoline(void) 178 + void kretprobe_trampoline(void) 179 179 { 180 180 asm volatile("nop"); 181 181 asm volatile("nop"); ··· 193 193 { 194 194 unsigned long orig_ret_address; 195 195 196 - orig_ret_address = __kretprobe_trampoline_handler(regs, trampoline_p.addr, NULL); 196 + orig_ret_address = __kretprobe_trampoline_handler(regs, NULL); 197 197 instruction_pointer_set(regs, orig_ret_address); 198 198 199 199 return 1;
+1 -1
arch/powerpc/kernel/kprobes.c
··· 417 417 { 418 418 unsigned long orig_ret_address; 419 419 420 - orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 420 + orig_ret_address = __kretprobe_trampoline_handler(regs, NULL); 421 421 /* 422 422 * We get here through one of two paths: 423 423 * 1. by taking a trap -> kprobe_handler() -> here
+1 -1
arch/riscv/kernel/probes/kprobes.c
··· 347 347 348 348 void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 349 349 { 350 - return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 350 + return (void *)kretprobe_trampoline_handler(regs, NULL); 351 351 } 352 352 353 353 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+1 -1
arch/s390/kernel/kprobes.c
··· 343 343 */ 344 344 static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 345 345 { 346 - regs->psw.addr = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 346 + regs->psw.addr = __kretprobe_trampoline_handler(regs, NULL); 347 347 /* 348 348 * By returning a non-zero value, we are telling 349 349 * kprobe_handler() that we don't want the post_handler
+1 -1
arch/sh/kernel/kprobes.c
··· 303 303 */ 304 304 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 305 305 { 306 - regs->pc = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 306 + regs->pc = __kretprobe_trampoline_handler(regs, NULL); 307 307 308 308 return 1; 309 309 }
+1 -1
arch/sparc/kernel/kprobes.c
··· 451 451 { 452 452 unsigned long orig_ret_address = 0; 453 453 454 - orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); 454 + orig_ret_address = __kretprobe_trampoline_handler(regs, NULL); 455 455 regs->tpc = orig_ret_address; 456 456 regs->tnpc = orig_ret_address + 4; 457 457
-1
arch/x86/include/asm/kprobes.h
··· 49 49 extern const int kretprobe_blacklist_size; 50 50 51 51 void arch_remove_kprobe(struct kprobe *p); 52 - asmlinkage void kretprobe_trampoline(void); 53 52 54 53 extern void arch_kprobe_override_function(struct pt_regs *regs); 55 54
+1 -1
arch/x86/kernel/kprobes/core.c
··· 1064 1064 regs->ip = (unsigned long)&kretprobe_trampoline; 1065 1065 regs->orig_ax = ~0UL; 1066 1066 1067 - return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, &regs->sp); 1067 + return (void *)kretprobe_trampoline_handler(regs, &regs->sp); 1068 1068 } 1069 1069 NOKPROBE_SYMBOL(trampoline_handler); 1070 1070
+13 -5
include/linux/kprobes.h
··· 188 188 struct pt_regs *regs); 189 189 extern int arch_trampoline_kprobe(struct kprobe *p); 190 190 191 + void kretprobe_trampoline(void); 192 + /* 193 + * Since some architecture uses structured function pointer, 194 + * use dereference_function_descriptor() to get real function address. 195 + */ 196 + static nokprobe_inline void *kretprobe_trampoline_addr(void) 197 + { 198 + return dereference_kernel_function_descriptor(kretprobe_trampoline); 199 + } 200 + 191 201 /* If the trampoline handler called from a kprobe, use this version */ 192 202 unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, 193 - void *trampoline_address, 194 - void *frame_pointer); 203 + void *frame_pointer); 195 204 196 205 static nokprobe_inline 197 206 unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, 198 - void *trampoline_address, 199 - void *frame_pointer) 207 + void *frame_pointer) 200 208 { 201 209 unsigned long ret; 202 210 /* ··· 213 205 * be running at this point. 214 206 */ 215 207 kprobe_busy_begin(); 216 - ret = __kretprobe_trampoline_handler(regs, trampoline_address, frame_pointer); 208 + ret = __kretprobe_trampoline_handler(regs, frame_pointer); 217 209 kprobe_busy_end(); 218 210 219 211 return ret;
+1 -2
kernel/kprobes.c
··· 1864 1864 #ifdef CONFIG_KRETPROBES 1865 1865 1866 1866 unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, 1867 - void *trampoline_address, 1868 1867 void *frame_pointer) 1869 1868 { 1870 1869 kprobe_opcode_t *correct_ret_addr = NULL; ··· 1878 1879 1879 1880 BUG_ON(ri->fp != frame_pointer); 1880 1881 1881 - if (ri->ret_addr != trampoline_address) { 1882 + if (ri->ret_addr != kretprobe_trampoline_addr()) { 1882 1883 correct_ret_addr = ri->ret_addr; 1883 1884 /* 1884 1885 * This is the real return address. Any other