Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp848013yba; Wed, 24 Apr 2019 10:33:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqxjGEj0FK7/LGHfPTelMdCWFyEs19sD26yo4MCPBWsdLzdV8Ia2nMSMhDBlTPSqGv9Ei/Fq X-Received: by 2002:a17:902:2b87:: with SMTP id l7mr34003793plb.130.1556127227492; Wed, 24 Apr 2019 10:33:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556127227; cv=none; d=google.com; s=arc-20160816; b=rCHLDxfYJ0pD0luFn0WHjApF9ykVEEnTKd3tf63uEQXoZD8RgE6C56HbNmOJZXlY2f GAUJdorDXRUSwEBwv4Z13ks8PN2RK+J4ok8KxCUASuEJowuiSOkJRqsQGNLkQiuur4Rq 02xsSs3EdNRK84/5ANILJD3pHOvlpUSBbY6sBKsM4cCZQRvC1f5uKZFJ1leO6jonhIO5 yQ4IUd3LDhDEtDGxdgCf1ajB5/jeFAbaTREGyLZqqYTdkgtqP2C1gQtjNyWZ5zQJspf0 i2aF1ZWX+izPL8EgN7ZrPA7xaUrTfd7saHnxmvm+HiE1GJ7ue8JjBaQIZakdmUWugIsk Oflw== 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=c7zlZCEdYFUbqCy8k20TNySqcyv2SVvKkApFB2PMe3s=; b=LyCYQUGUbDI2XMzxhiWRMYXOgE3WYlzj9zV3yylj7VN1Itw0wb1BT0mPgHmAL0JfAP mJP0w4H8OPDS4+luJi9aTHL6Jsalmu/rDUt9O26vWLgFiAYOulzXjZkhZqJBLq4B4QAy aEiAKHNR/YxBMi24HyfgttEvILULKPcd9rkjI1bOl/48bC8P+ebMY5YRO+gsigiyTjie jQBUX/wUNLxGdZflHfWEuzlCoXr5jHC8NRYBaTzXOhD7YW6tiyq/g/2r1cY8Sz21SNzK kf6IQ5LqaDD+rHhcG/lNZiy1JppJG9Wd10uBTeO4iU1sgACq/hn2sLSfADAJdkjdXJKZ gHTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=m5g77h6v; 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 143si17617301pga.118.2019.04.24.10.33.32; Wed, 24 Apr 2019 10:33:47 -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=m5g77h6v; 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 S2391212AbfDXRb6 (ORCPT + 99 others); Wed, 24 Apr 2019 13:31:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:58380 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390475AbfDXRbw (ORCPT ); Wed, 24 Apr 2019 13:31:52 -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 BDD8521915; Wed, 24 Apr 2019 17:31:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1556127111; bh=Hra5CC/kccN76sIH9vxco1aSEHssXT927s3p/imH6tw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m5g77h6vf0LpCsk524BOnlsrdMV9u19FQd2NSWfFItUMdUxmRh9UsnxUgUPMYpmVg 10Z1mI5dsJ/tUDejAWRFe/5Om4IbBQPLfM5QVsLcxnqX6Wk7BgReRswDA3GeIOYHpN R8pTFkh14lTtKs8oqLvjSAg0KrNE836UDTbf+EMA= 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.19 66/96] x86/kprobes: Verify stack frame on kretprobe Date: Wed, 24 Apr 2019 19:10:11 +0200 Message-Id: <20190424170924.200628922@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190424170919.829037226@linuxfoundation.org> References: <20190424170919.829037226@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 @@ -569,6 +569,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; @@ -759,15 +760,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; @@ -789,8 +796,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) /* @@ -808,6 +832,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 @@ -173,6 +173,7 @@ struct kretprobe_instance { struct kretprobe *rp; kprobe_opcode_t *ret_addr; struct task_struct *task; + void *fp; char data[0]; };