Commit ad05711c authored by David A. Long's avatar David A. Long Committed by Catalin Marinas

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: default avatarDavid A. Long <dave.long@linaro.org>
Acked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 7f1d642f
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#define __ARCH_WANT_KPROBES_INSN_SLOT #define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE 1 #define MAX_INSN_SIZE 1
#define MAX_STACK_SIZE 128
#define flush_insn_slot(p) do { } while (0) #define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0 #define kretprobe_blacklist_size 0
...@@ -47,7 +46,6 @@ struct kprobe_ctlblk { ...@@ -47,7 +46,6 @@ struct kprobe_ctlblk {
struct prev_kprobe prev_kprobe; struct prev_kprobe prev_kprobe;
struct kprobe_step_ctx ss_ctx; struct kprobe_step_ctx ss_ctx;
struct pt_regs jprobe_saved_regs; struct pt_regs jprobe_saved_regs;
char jprobes_stack[MAX_STACK_SIZE];
}; };
void arch_remove_kprobe(struct kprobe *); void arch_remove_kprobe(struct kprobe *);
......
...@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); ...@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
static void __kprobes static void __kprobes
post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
static inline unsigned long min_stack_size(unsigned long addr)
{
unsigned long size;
if (on_irq_stack(addr, raw_smp_processor_id()))
size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
else
size = (unsigned long)current_thread_info() + THREAD_START_SP - addr;
return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
}
static void __kprobes arch_prepare_ss_slot(struct kprobe *p) static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
{ {
/* prepare insn slot */ /* prepare insn slot */
...@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{ {
struct jprobe *jp = container_of(p, struct jprobe, kp); struct jprobe *jp = container_of(p, struct jprobe, kp);
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
long stack_ptr = kernel_stack_pointer(regs);
kcb->jprobe_saved_regs = *regs; kcb->jprobe_saved_regs = *regs;
/* /*
* As Linus pointed out, gcc assumes that the callee * Since we can't be sure where in the stack frame "stacked"
* owns the argument space and could overwrite it, e.g. * pass-by-value arguments are stored we just don't try to
* tailcall optimization. So, to be absolutely safe * duplicate any of the stack. Do not use jprobes on functions that
* we also save and restore enough stack bytes to cover * use more than 64 bytes (after padding each to an 8 byte boundary)
* the argument area. * of arguments, or pass individual arguments larger than 16 bytes.
*/ */
kasan_disable_current();
memcpy(kcb->jprobes_stack, (void *)stack_ptr,
min_stack_size(stack_ptr));
kasan_enable_current();
instruction_pointer_set(regs, (unsigned long) jp->entry); instruction_pointer_set(regs, (unsigned long) jp->entry);
preempt_disable(); preempt_disable();
...@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
} }
unpause_graph_tracing(); unpause_graph_tracing();
*regs = kcb->jprobe_saved_regs; *regs = kcb->jprobe_saved_regs;
kasan_disable_current();
memcpy((void *)stack_addr, kcb->jprobes_stack,
min_stack_size(stack_addr));
kasan_enable_current();
preempt_enable_no_resched(); preempt_enable_no_resched();
return 1; return 1;
} }
......
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