Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp869533yba; Wed, 24 Apr 2019 10:56:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqyBkv1lFzAt1JBWqEc/CXDoS9zwVHrYdp/3EWGEHlwkKAXf/8arQ5YRiiC3LbzyjX85ss+q X-Received: by 2002:a63:4721:: with SMTP id u33mr2010320pga.199.1556128570778; Wed, 24 Apr 2019 10:56:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556128570; cv=none; d=google.com; s=arc-20160816; b=V8jkwE95npfHqPBqOKLL+ao6oiINWBaOu64YfrBfCoS3SMQ3SdGZAMqNpxU0u4AGJm 2RenVesNye07bq0ztrkr1MptOMdwgXY7zGZ0ob8RsXsGALtqLpsRhkiADu0CWHrb6SMs 2X4EGeYXe+dZXSqz7ldVF6Jo59FFe+QVSoGj75FCfM/SvDOrYTUEaYTDVzjXjGSptJRk fkOmI4eHFzBV3587h5/b1zL58FVwoG2LOcqyWYB0KkzuGT4uAxByg7umzDzeUt/Ggz2I kymCqe9GeDUJzGsW7YQ8JVX9Q6VAalIEFmIWH6/1F78nyfeDyeYfiEtXoFBnr3NgPl5P BExw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=bhaYT9iNy8WgIMatYPSmzEffOIb7yaItUn12Qy2bdAo=; b=iEXP9cktpKilzE58wwyxufm/ZvVTFi+urKf+yaVDvgAeByp1L7cDLwW2dxFtVfEzlm QJ4aOofyWE2s/gloxFlpAN4jek5prFk5p2vXmY7LbCsLJmFf9pQi5oBaviJibkFvC2Rd e7GWTxbSnANuGPso6F7rqlpEyGmpw56xcEAyHufKvJqNi5Gyqn1IK1xayt1hn43tjoLU P0j4ty3DfrBmALWejUaOINuEjIC6E5ZaXEDPBNYXAY2LdWzxZHlCpETF/5/tOQh0sG8C 0kpcW2IFOEFfjKQEv3cQevkmVoyyrl2aGOtjjDfhZM9GEQqUtqxPiGGIm5lsc0wgEq7B BUyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=F3z2yFnA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q4si19244310plr.376.2019.04.24.10.55.55; Wed, 24 Apr 2019 10:56:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=F3z2yFnA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390476AbfDXR1b (ORCPT + 99 others); Wed, 24 Apr 2019 13:27:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:53482 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390451AbfDXR13 (ORCPT ); Wed, 24 Apr 2019 13:27:29 -0400 Received: from localhost (62-193-50-229.as16211.net [62.193.50.229]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 525DC205ED; Wed, 24 Apr 2019 17:27:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1556126848; bh=Fvn/+z9DE2N8e+SEL3pFB7IPyDTp2jA0yF2crBzI3aw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F3z2yFnAihVahCI2mHjktHqBbB9EVIis4tQnEiRZzfMmxLbziBaPfISuF8n0qkfwD 3WldRkyQ/MxkGmaisp3n7It1xSsroYo3AFrkUNrrTQEDQhVupllHWWirkCHJppCWYQ PGojR22kkGa18eQg5gcby9UnYsL1yHZ+rL3yQE+M= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andrea Righi , Masami Hiramatsu , Steven Rostedt , Linus Torvalds , Mathieu Desnoyers , Peter Zijlstra , Thomas Gleixner , Ingo Molnar Subject: [PATCH 4.14 39/70] x86/kprobes: Verify stack frame on kretprobe Date: Wed, 24 Apr 2019 19:09:59 +0200 Message-Id: <20190424170912.806338347@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190424170906.751869122@linuxfoundation.org> References: <20190424170906.751869122@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Masami Hiramatsu commit 3ff9c075cc767b3060bdac12da72fc94dd7da1b8 upstream. Verify the stack frame pointer on kretprobe trampoline handler, If the stack frame pointer does not match, it skips the wrong entry and tries to find correct one. This can happen if user puts the kretprobe on the function which can be used in the path of ftrace user-function call. Such functions should not be probed, so this adds a warning message that reports which function should be blacklisted. Tested-by: Andrea Righi Signed-off-by: Masami Hiramatsu Acked-by: Steven Rostedt Cc: Linus Torvalds Cc: Mathieu Desnoyers Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/155094059185.6137.15527904013362842072.stgit@devbox Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/kprobes/core.c | 26 ++++++++++++++++++++++++++ include/linux/kprobes.h | 1 + 2 files changed, 27 insertions(+) --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -553,6 +553,7 @@ void arch_prepare_kretprobe(struct kretp unsigned long *sara = stack_addr(regs); ri->ret_addr = (kprobe_opcode_t *) *sara; + ri->fp = sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; @@ -754,15 +755,21 @@ __visible __used void *trampoline_handle unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; kprobe_opcode_t *correct_ret_addr = NULL; + void *frame_pointer; + bool skipped = false; INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); /* fixup registers */ #ifdef CONFIG_X86_64 regs->cs = __KERNEL_CS; + /* On x86-64, we use pt_regs->sp for return address holder. */ + frame_pointer = ®s->sp; #else regs->cs = __KERNEL_CS | get_kernel_rpl(); regs->gs = 0; + /* On x86-32, we use pt_regs->flags for return address holder. */ + frame_pointer = ®s->flags; #endif regs->ip = trampoline_address; regs->orig_ax = ~0UL; @@ -784,8 +791,25 @@ __visible __used void *trampoline_handle if (ri->task != current) /* another task is sharing our hash bucket */ continue; + /* + * Return probes must be pushed on this hash list correct + * order (same as return order) so that it can be poped + * correctly. However, if we find it is pushed it incorrect + * order, this means we find a function which should not be + * probed, because the wrong order entry is pushed on the + * path of processing other kretprobe itself. + */ + if (ri->fp != frame_pointer) { + if (!skipped) + pr_warn("kretprobe is stacked incorrectly. Trying to fixup.\n"); + skipped = true; + continue; + } orig_ret_address = (unsigned long)ri->ret_addr; + if (skipped) + pr_warn("%ps must be blacklisted because of incorrect kretprobe order\n", + ri->rp->kp.addr); if (orig_ret_address != trampoline_address) /* @@ -803,6 +827,8 @@ __visible __used void *trampoline_handle if (ri->task != current) /* another task is sharing our hash bucket */ continue; + if (ri->fp != frame_pointer) + continue; orig_ret_address = (unsigned long)ri->ret_addr; if (ri->rp && ri->rp->handler) { --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -198,6 +198,7 @@ struct kretprobe_instance { struct kretprobe *rp; kprobe_opcode_t *ret_addr; struct task_struct *task; + void *fp; char data[0]; };