From patchwork Fri Apr 8 00:51:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 12805980 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA9D4C433EF for ; Fri, 8 Apr 2022 00:52:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=l+oDOBY+QEJYmBd6aEPsK/vW8+Tl0eusHg58+dFQ0J0=; b=mHqHsBsBhNCjXp eq+N5des41XKsDURvm9vKkrm27t9KqPD8AdfZ/WOA/v8O/ge7oWycIAB8B2zcbNoEMU9H7dce8uyN 8QvVyWssiNV0hdeU1/r6ATCsHVKL6gnbMQWI8DHieC8JsRF1np2ypXrheKWpEBEU+dswPJ5+41gvj rvI9gtOkhbQhbmTMVM+EDzNGt0ctU3oGI/eTc1OK/A8R01sTW7TtQ+YBAJQEfItbiI5X6tSuc1bts amU/HNlAyOHmiBwCgYA7vMR7KGMQHF+WmPrfJNNKOqLjHAOAsIl3Qt25HdXYugyBZ1Itp0zSJzd5R k91ZxRPR11uE9umpC67g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nccqG-00ET19-3J; Fri, 08 Apr 2022 00:51:12 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nccqB-00ESzf-T8 for linux-arm-kernel@lists.infradead.org; Fri, 08 Apr 2022 00:51:09 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 73010617F1; Fri, 8 Apr 2022 00:51:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92372C385A9; Fri, 8 Apr 2022 00:51:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1649379066; bh=qU7NQO8a/GNTqpF3kK+hxQlG2bDuw47+HzlGrFENsk0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GOQSPJ8bHkuyeDVLE6PnkAGeUamFLQFl8cos02fJ8bIyktW4ZeXboUeddgG/NMIa2 CaNnuHS++W12Ut17ouCCXqwYJ+xzcmWBztMK5sTWcpSG2jxXAhAPiqn3n3qyVGs5RI DEX5EtMR9GxZz4fdnpitv3nanTaZj3/2+A6vWsYXPUWdbqzEHpBZmqz6Zntz34tHA7 C5LMwWG4dgQH311WFakZVAhou+Sh0SvqdPRsCt6Y3c6wmsRt18XcHRxwCox1tw8pDO criUsaXqR8aM7fK2H+qWAIoPJsfFGnFNwrCMX4p5DabHPNtmE4VZMAFZZAQqElfIOi 92WbAySEbNahQ== From: Masami Hiramatsu To: Alexei Starovoitov , Alexei Starovoitov Cc: Daniel Borkmann , Shubham Bansal , Andrii Nakryiko , Masami Hiramatsu , bpf@vger.kernel.org, kernel-team@fb.com, Jiri Olsa , Steven Rostedt , "Naveen N . Rao" , Anil S Keshavamurthy , "David S . Miller" , linux-kernel@vger.kernel.org, Mark Rutland , Will Deacon , Ard Biesheuvel , Russell King , Catalin Marinas , linux-arm-kernel@lists.infradead.org Subject: [PATCH bpf v2 2/4] rethook, fprobe, kprobes: Check a failure in the rethook_hook() Date: Fri, 8 Apr 2022 09:51:00 +0900 Message-Id: <164937905999.1272679.6572597960911139308.stgit@devnote2> X-Mailer: git-send-email 2.25.1 In-Reply-To: <164937903547.1272679.7244379141135199176.stgit@devnote2> References: <164937903547.1272679.7244379141135199176.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220407_175108_078170_F458FF0A X-CRM114-Status: GOOD ( 19.23 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since there are possible to fail to hook the function return (depends on archtecutre implememtation), rethook_hook() should return the error in that case and caller must check it. Signed-off-by: Masami Hiramatsu --- arch/x86/kernel/rethook.c | 4 +++- include/linux/rethook.h | 4 ++-- kernel/kprobes.c | 8 +++++--- kernel/trace/fprobe.c | 5 ++++- kernel/trace/rethook.c | 12 ++++++++++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c index 8a1c0111ae79..c92b4875e3b9 100644 --- a/arch/x86/kernel/rethook.c +++ b/arch/x86/kernel/rethook.c @@ -114,7 +114,7 @@ void arch_rethook_fixup_return(struct pt_regs *regs, } NOKPROBE_SYMBOL(arch_rethook_fixup_return); -void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +int arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) { unsigned long *stack = (unsigned long *)regs->sp; @@ -123,5 +123,7 @@ void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mc /* Replace the return addr with trampoline addr */ stack[0] = (unsigned long) arch_rethook_trampoline; + + return 0; } NOKPROBE_SYMBOL(arch_rethook_prepare); diff --git a/include/linux/rethook.h b/include/linux/rethook.h index c8ac1e5afcd1..07b9c6663b8e 100644 --- a/include/linux/rethook.h +++ b/include/linux/rethook.h @@ -63,12 +63,12 @@ void rethook_free(struct rethook *rh); void rethook_add_node(struct rethook *rh, struct rethook_node *node); struct rethook_node *rethook_try_get(struct rethook *rh); void rethook_recycle(struct rethook_node *node); -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); unsigned long rethook_find_ret_addr(struct task_struct *tsk, unsigned long frame, struct llist_node **cur); /* Arch dependent code must implement arch_* and trampoline code */ -void arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); void arch_rethook_trampoline(void); /** diff --git a/kernel/kprobes.c b/kernel/kprobes.c index dbe57df2e199..7fd7f1195bde 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2109,10 +2109,12 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) ri = container_of(rhn, struct kretprobe_instance, node); - if (rp->entry_handler && rp->entry_handler(ri, regs)) + if (rp->entry_handler && rp->entry_handler(ri, regs)) { rethook_recycle(rhn); - else - rethook_hook(rhn, regs, kprobe_ftrace(p)); + } else if (rethook_hook(rhn, regs, kprobe_ftrace(p)) < 0) { + rethook_recycle(rhn); + rp->nmissed++; + } return 0; } diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 89d9f994ebb0..d3b13294d545 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -48,7 +48,10 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, } fpr = container_of(rh, struct fprobe_rethook_node, node); fpr->entry_ip = ip; - rethook_hook(rh, ftrace_get_regs(fregs), true); + if (rethook_hook(rh, ftrace_get_regs(fregs), true) < 0) { + rethook_recycle(rh); + fp->nmissed++; + } } out: diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c index b56833700d23..e7db83438e45 100644 --- a/kernel/trace/rethook.c +++ b/kernel/trace/rethook.c @@ -174,11 +174,19 @@ NOKPROBE_SYMBOL(rethook_try_get); * from ftrace (mcount) callback, @mcount must be set true. If this is called * from the real function entry (e.g. kprobes) @mcount must be set false. * This is because the way to hook the function return depends on the context. + * This returns 0 if succeeded to hook the function return, or -errno if + * failed. */ -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) { - arch_rethook_prepare(node, regs, mcount); + int ret; + + ret = arch_rethook_prepare(node, regs, mcount); + if (ret < 0) + return ret; + __llist_add(&node->llist, ¤t->rethooks); + return 0; } NOKPROBE_SYMBOL(rethook_hook);