From patchwork Wed Aug 10 20:44:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 73695 Delivered-To: patches@linaro.org Received: by 10.140.29.52 with SMTP id a49csp586773qga; Wed, 10 Aug 2016 13:44:55 -0700 (PDT) X-Received: by 10.55.77.11 with SMTP id a11mr6337748qkb.112.1470861895304; Wed, 10 Aug 2016 13:44:55 -0700 (PDT) Return-Path: Received: from mail-qk0-x236.google.com (mail-qk0-x236.google.com. [2607:f8b0:400d:c09::236]) by mx.google.com with ESMTPS id j4si5107120qkf.317.2016.08.10.13.44.55 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Aug 2016 13:44:55 -0700 (PDT) Received-SPF: pass (google.com: domain of dave.long@linaro.org designates 2607:f8b0:400d:c09::236 as permitted sender) client-ip=2607:f8b0:400d:c09::236; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of dave.long@linaro.org designates 2607:f8b0:400d:c09::236 as permitted sender) smtp.mailfrom=dave.long@linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by mail-qk0-x236.google.com with SMTP id t7so55993905qkh.0 for ; Wed, 10 Aug 2016 13:44:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=5V1ylDWJ0E2GvKy3FJ3ogyDWZYOnYOyOnmG7rloi2Ng=; b=NIrfXxKCUWdIZcDeUzXT5egFhz38M4O3jIa6C4ttlrbLcCHBcYxECxv5K8PjpQcJZx aHZZDNvTJAYGWNs5z53KnwgRo+Ai4mlF2eXDiF3OH0aRFPNgzqyJHGvsroEhSMu3gVCJ pmD1pifzzlJ3mX5PUH3JdUlV4lrD3aorjidgc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=5V1ylDWJ0E2GvKy3FJ3ogyDWZYOnYOyOnmG7rloi2Ng=; b=mr5Kv1jdqcxowDrDdNnerUDml+fq6fLO7fFxNTHK5VSAsrtrZ2YNaqoKVz+lafHJml E/Y8AlElA2Q2t6XyiupTK787feX+8eRBDo48q5PDFT12QOsnPTZFkqYW3K5DtwGab0CK LBykUwrRMCu25bToX9eziaFE2wu6Qf1BAmTXe4qHPyWF08VwJmh8mYIkq4AagRcUpvaZ 2AJ41RknWpBEAIham+MSJgM/rn1iFMEHBwocZhdoB4kpWvT11VNpwE+zvQzi4Otyv5kl KlVtWkPd+5UH/z9Y1XTKhcPUqhlA2+OeLVCx1krP5c9PJgtySEDiNh4n+oOc9Xchy//p 3+2g== X-Gm-Message-State: AEkooutKJHWGXP9xVG+qpKQoTM3V4mDyJsTDIWom86CI/hbJRn8Req3m+25RHr0jTkphsqlKDVo= X-Received: by 10.55.116.134 with SMTP id p128mr6560176qkc.165.1470861894854; Wed, 10 Aug 2016 13:44:54 -0700 (PDT) Return-Path: Received: from localhost.localdomain (pool-72-71-243-24.cncdnh.fast00.myfairpoint.net. [72.71.243.24]) by smtp.googlemail.com with ESMTPSA id e7sm24117539qtb.9.2016.08.10.13.44.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 Aug 2016 13:44:54 -0700 (PDT) From: David Long To: Catalin Marinas , Huang Shijie , James Morse , Marc Zyngier , Pratyush Anand , Sandeepa Prabhu , Will Deacon , William Cohen , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Steve Capper , Masami Hiramatsu , Li Bin Cc: Adam Buchbinder , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Andrew Morton , Andrey Ryabinin , Ard Biesheuvel , Christoffer Dall , Daniel Thompson , Dave P Martin , Jens Wiklander , Jisheng Zhang , John Blackwood , Mark Rutland , Petr Mladek , Robin Murphy , Suzuki K Poulose , Vladimir Murzin , Yang Shi , Zi Shen Lim , yalin wang , Mark Brown Subject: [PATCH 1/1] arm64: Remove stack duplicating code from jprobes Date: Wed, 10 Aug 2016 16:44:51 -0400 Message-Id: <1470861891-13315-1-git-send-email-dave.long@linaro.org> X-Mailer: git-send-email 2.5.0 From: "David A. Long" 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. Documenation 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 Acked-by: Masami Hiramatsu --- arch/arm64/include/asm/kprobes.h | 2 -- arch/arm64/kernel/probes/kprobes.c | 31 +++++-------------------------- 2 files changed, 5 insertions(+), 28 deletions(-) -- 2.5.0 diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h index 61b4915..1737aec 100644 --- a/arch/arm64/include/asm/kprobes.h +++ b/arch/arm64/include/asm/kprobes.h @@ -22,7 +22,6 @@ #define __ARCH_WANT_KPROBES_INSN_SLOT #define MAX_INSN_SIZE 1 -#define MAX_STACK_SIZE 128 #define flush_insn_slot(p) do { } while (0) #define kretprobe_blacklist_size 0 @@ -47,7 +46,6 @@ struct kprobe_ctlblk { struct prev_kprobe prev_kprobe; struct kprobe_step_ctx ss_ctx; struct pt_regs jprobe_saved_regs; - char jprobes_stack[MAX_STACK_SIZE]; }; void arch_remove_kprobe(struct kprobe *); diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index bf97685..c6b0f40 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); static void __kprobes 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) { /* prepare insn slot */ @@ -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 kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - long stack_ptr = kernel_stack_pointer(regs); kcb->jprobe_saved_regs = *regs; /* - * As Linus pointed out, gcc assumes that the callee - * owns the argument space and could overwrite it, e.g. - * tailcall optimization. So, to be absolutely safe - * we also save and restore enough stack bytes to cover - * the argument area. + * Since we can't be sure where in the stack frame "stacked" + * pass-by-value arguments are stored we just don't try to + * duplicate any of the stack. Do not use jprobes on functions that + * use more than 64 bytes (after padding each to an 8 byte boundary) + * 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); preempt_disable(); @@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } unpause_graph_tracing(); *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(); return 1; }