diff options
author | David A. Long <dave.long@linaro.org> | 2016-08-10 16:44:51 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2016-08-11 12:38:16 -0400 |
commit | ad05711cec12131e1277ce749a99d08ecf233aa7 (patch) | |
tree | ca1f1c19acc86fb174e59ceda8e1bd32279b2f95 /arch/arm64/kernel/probes | |
parent | 7f1d642fbb5c356519617c24757a0cbed7f800a8 (diff) |
arm64: Remove stack duplicating code from jprobes
Because the arm64 calling standard allows stacked function arguments to be
anywhere in the stack frame, do not attempt to duplicate the stack frame for
jprobes handler functions.
Documentation changes to describe this issue have been broken out into a
separate patch in order to simultaneously address them in other
architecture(s).
Signed-off-by: David A. Long <dave.long@linaro.org>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/probes')
-rw-r--r-- | arch/arm64/kernel/probes/kprobes.c | 31 |
1 files changed, 5 insertions, 26 deletions
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index bf9768588288..c6b0f40620d8 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c | |||
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | |||
41 | static void __kprobes | 41 | static void __kprobes |
42 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); | 42 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); |
43 | 43 | ||
44 | static inline unsigned long min_stack_size(unsigned long addr) | ||
45 | { | ||
46 | unsigned long size; | ||
47 | |||
48 | if (on_irq_stack(addr, raw_smp_processor_id())) | ||
49 | size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr; | ||
50 | else | ||
51 | size = (unsigned long)current_thread_info() + THREAD_START_SP - addr; | ||
52 | |||
53 | return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack)); | ||
54 | } | ||
55 | |||
56 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) | 44 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) |
57 | { | 45 | { |
58 | /* prepare insn slot */ | 46 | /* prepare insn slot */ |
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
489 | { | 477 | { |
490 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 478 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
491 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 479 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
492 | long stack_ptr = kernel_stack_pointer(regs); | ||
493 | 480 | ||
494 | kcb->jprobe_saved_regs = *regs; | 481 | kcb->jprobe_saved_regs = *regs; |
495 | /* | 482 | /* |
496 | * As Linus pointed out, gcc assumes that the callee | 483 | * Since we can't be sure where in the stack frame "stacked" |
497 | * owns the argument space and could overwrite it, e.g. | 484 | * pass-by-value arguments are stored we just don't try to |
498 | * tailcall optimization. So, to be absolutely safe | 485 | * duplicate any of the stack. Do not use jprobes on functions that |
499 | * we also save and restore enough stack bytes to cover | 486 | * use more than 64 bytes (after padding each to an 8 byte boundary) |
500 | * the argument area. | 487 | * of arguments, or pass individual arguments larger than 16 bytes. |
501 | */ | 488 | */ |
502 | kasan_disable_current(); | ||
503 | memcpy(kcb->jprobes_stack, (void *)stack_ptr, | ||
504 | min_stack_size(stack_ptr)); | ||
505 | kasan_enable_current(); | ||
506 | 489 | ||
507 | instruction_pointer_set(regs, (unsigned long) jp->entry); | 490 | instruction_pointer_set(regs, (unsigned long) jp->entry); |
508 | preempt_disable(); | 491 | preempt_disable(); |
@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
554 | } | 537 | } |
555 | unpause_graph_tracing(); | 538 | unpause_graph_tracing(); |
556 | *regs = kcb->jprobe_saved_regs; | 539 | *regs = kcb->jprobe_saved_regs; |
557 | kasan_disable_current(); | ||
558 | memcpy((void *)stack_addr, kcb->jprobes_stack, | ||
559 | min_stack_size(stack_addr)); | ||
560 | kasan_enable_current(); | ||
561 | preempt_enable_no_resched(); | 540 | preempt_enable_no_resched(); |
562 | return 1; | 541 | return 1; |
563 | } | 542 | } |