From patchwork Mon Mar 15 16:57:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhavan T. Venkataraman" X-Patchwork-Id: 12140131 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC5AEC433DB for ; Mon, 15 Mar 2021 17:02:09 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5205664D9A for ; Mon, 15 Mar 2021 17:02:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5205664D9A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; 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:To:From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=usdfoZSejBi2Pkg+wQzuhgdUTe95Xld5qwdqmxF2mAM=; b=WWvRQdQKAX9CiTIm+KQsbtcDO JbMuPByVGAUvf020nEtLAdW+s74jrT8mWKtN065kZPAFl3yZUym3U2hpJK/XkAJ7IqCjpNn5QjCaP 9GMdY9UgiZPB5C16bVlFdpWwPS6YNwVAeCk1GrCpQyJXlwwE/ZmZeARE0a6R0pOXTArvTsYSSw7rx C4um2uWQACxNJWJL/2qBiXmVlCuwEge4btyIZ66YEeqXcT8cnbnyLw+3bu8hn+JJLUdzlrsxwN2vw qnKHYzIBn6ekjKd9cROStM+4DuetaZZWpUFcqGOf0HbBYZIWXzejOZUSie/EUVGEizNQMs9RKONfT Ohr2Wp3Tw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqZq-00GQOA-IG; Mon, 15 Mar 2021 17:00:22 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lLqXr-00GPox-Vv for linux-arm-kernel@lists.infradead.org; Mon, 15 Mar 2021 16:58:23 +0000 Received: from x64host.home (unknown [47.187.194.202]) by linux.microsoft.com (Postfix) with ESMTPSA id 5D3FD20B24C9; Mon, 15 Mar 2021 09:58:16 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5D3FD20B24C9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1615827497; bh=U+g0k+CbNn5bvnLnkW0oWUHs8xX5CpmhC3AM4YySraA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TTELecyPokPX3waxtRE8n2B5zh3IpIDfunnF9vcMo7BWdiR0m16rpdEVxyRQlm2dZ hDRqbTIGUQi+Vqa+j2lzZgmXt37RIVSxofNatCRvnfdBaUXPtihaj4L5Ro3QBv30SO qNLTLIpLbXSzPFynG2eQVOxPrVDjTpRf+Lrccos0= From: madvenka@linux.microsoft.com To: broonie@kernel.org, mark.rutland@arm.com, jpoimboe@redhat.com, jthierry@redhat.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v2 7/8] arm64: Detect kretprobed functions in stack trace Date: Mon, 15 Mar 2021 11:57:59 -0500 Message-Id: <20210315165800.5948-8-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210315165800.5948-1-madvenka@linux.microsoft.com> References: <5997dfe8d261a3a543667b83c902883c1e4bd270> <20210315165800.5948-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210315_165820_771405_47671EA9 X-CRM114-Status: GOOD ( 18.89 ) 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 From: "Madhavan T. Venkataraman" When a kretprobe is active for a function, the function's return address in its stack frame is modified to point to the kretprobe trampoline. When the function returns, the frame is popped and control is transferred to the trampoline. The trampoline eventually returns to the original return address. If a stack walk is done within the function (or any functions that get called from there), the stack trace will only show the trampoline and the not the original caller. Detect this and mark the stack trace as unreliable. Also, if the trampoline and the functions it calls do a stack trace, that stack trace will also have the same problem. Detect this as well. This is done by looking up the symbol table entry for the trampoline and checking if the return PC in a frame falls anywhere in the trampoline function. Signed-off-by: Madhavan T. Venkataraman --- arch/arm64/kernel/stacktrace.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 358aae3906d7..752b77f11c61 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -18,6 +18,26 @@ #include #include +#ifdef CONFIG_KRETPROBES +static bool kretprobe_detected(struct stackframe *frame) +{ + static char kretprobe_name[KSYM_NAME_LEN]; + static unsigned long kretprobe_pc, kretprobe_end_pc; + unsigned long pc, offset, size; + + if (!kretprobe_pc) { + pc = (unsigned long) kretprobe_trampoline; + if (!kallsyms_lookup(pc, &size, &offset, NULL, kretprobe_name)) + return false; + + kretprobe_pc = pc - offset; + kretprobe_end_pc = kretprobe_pc + size; + } + + return frame->pc >= kretprobe_pc && frame->pc < kretprobe_end_pc; +} +#endif + static void check_if_reliable(unsigned long fp, struct stackframe *frame, struct stack_info *info) { @@ -111,6 +131,29 @@ static void check_if_reliable(unsigned long fp, struct stackframe *frame, frame->reliable = false; return; } + +#ifdef CONFIG_KRETPROBES + /* + * The return address of a function that has an active kretprobe + * is modified in the stack frame to point to a trampoline. So, + * the original return address is not available on the stack. + * + * A stack trace taken while executing the function (and its + * descendants) will not show the original caller. So, mark the + * stack trace as unreliable if the trampoline shows up in the + * stack trace. (Obtaining the original return address from + * task->kretprobe_instances seems problematic and not worth the + * effort). + * + * The stack trace taken while inside the trampoline and functions + * called by the trampoline have the same problem as above. This + * is also covered by kretprobe_detected() using a range check. + */ + if (kretprobe_detected(frame)) { + frame->reliable = false; + return; + } +#endif } /*