From mboxrd@z Thu Jan 1 00:00:00 1970 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 6F8F9ECAAA1 for ; Fri, 9 Sep 2022 18:08:35 +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:Message-ID:Subject:Cc:To: From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=0Tfx/4xFzndpgb42oDkQlwy08jvE3xwWb0N0Xybr/Do=; b=bFAt8dq+dc7LLY CYOvlQzUYsby+5qWImgfSUJaVwcl/l9yqxgqYIAb0P/HOaOjhn3AnRZrtDkDgjJ8shKj+Q4mSVL4r lciueeehzGLXmBb1KLIt/+0HwtMZ5HknjiAXzkLasaIhcAICw1qFgIie6rUyacrdNHz3jjl81ZRBw 6mN+v0NKIrpmXvmGD7qdaQ70Dfc1O6ynENKal3rtMppU5vxKYJ2DrRgM9VgkfWtjTJncNtPHGpZCX JQ3sc0yL6dNPRvwhkZk4qKr7vciEOlGHRQOD5Ou9BHHa6CJAQ/KtDeO2WLU5pk7klRGU3edV9IfRl BTuMANCLzlxquYxQ8WlA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oWiPI-00101f-Tq; Fri, 09 Sep 2022 18:07:13 +0000 Received: from ams.source.kernel.org ([145.40.68.75]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oWiPF-00100a-Sb for linux-arm-kernel@lists.infradead.org; Fri, 09 Sep 2022 18:07:11 +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 ams.source.kernel.org (Postfix) with ESMTPS id 7D4DBB82608; Fri, 9 Sep 2022 18:07:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8BB15C433C1; Fri, 9 Sep 2022 18:07:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1662746827; bh=pf+MkFLWJgD9sdFlaDtSVC4UtcaGGPaQQ4xQWTkp2YA=; h=Date:From:To:Cc:Subject:From; b=jee/xnQyv2hknTpmqBgcmiaHSiptpKQQlBiFBYY1zADL9dnmjY4hVytWp5t95+lDU lAwMwmmVkmvEVsI4qLbLsLn66jkwrV2hYIFdrYIeHJI8NcC3IESptUt8MkVMgLcLwh xSoBWHzM6p0kKopzlIAoPL/TgLWDilUiDnxERZywDHWm46Tfxwzvvd8u8XPQrg9Lnp IosJRW4W1/gJVo0mGvap/J3U1jbN/n6HPasUykdMP4iPbSkTA2ZpTylTQ213b//sqP hOQXkYEbxCzNpLfA/MtfZEoHmrOPX/r1z1ngaPSIDSJTh/jLqWzN3pBMjxQ077pxTa h0LudLk0O23cw== Date: Fri, 9 Sep 2022 11:07:04 -0700 From: Josh Poimboeuf To: linux-toolchains@vger.kernel.org Cc: Peter Zijlstra , Indu Bhagat , Nick Desaulniers , linux-kernel@vger.kernel.org, "Jose E. Marchesi" , Miroslav Benes , Mark Rutland , Will Deacon , x86@kernel.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Ard Biesheuvel , Chen Zhongjin , Sathvika Vasireddy , Christophe Leroy , Mark Brown Subject: [RFC] Objtool toolchain proposal: -fannotate-{jump-table,noreturn} Message-ID: <20220909180704.jwwed4zhwvin7uyi@treble> MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220909_110710_223778_2A1F49EA X-CRM114-Status: GOOD ( 17.53 ) 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: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi, Here's a preview of what I'm planning to discuss at the LPC toolchains microconference. Feel free to start the discussion early :-) This is a proposal for some new minor GCC/Clang features which would help objtool greatly. Background ---------- Objtool is a kernel-specific tool which reverse engineers the control flow graph (CFG) of compiled objects. It then performs various validations, annotations, and modifications, mostly with the goal of improving robustness and security of the kernel. Objtool features which use the CFG include include: validation/generation of unwinding metadata; validation of Intel SMAP rules; and validation of kernel "noinstr" rules (preventing compiler instrumentation in certain critical sections). In general it's not feasible for the traditional toolchain to do any of this work, because the kernel has a lot of "blind spots" which the toolchain doesn't have visibility to, notably asm and inline asm. Manual .cfi annotations are very difficult to maintain and even more difficult to ensure correctness. Also, due to kernel live patching, the kernel relies on 100% correctness of unwinding metadata, whereas the toolchain treats it as a best effort. Challenges ---------- Reverse engineering the control flow graph is mostly quite straightforward, with two notable exceptions: 1) Jump tables (e.g., switch statements): Depending on the architecture, it's somewhere between difficult and impossible to reliabily identify which indirect jumps correspond to jump tables, and what are their corresponding intra-function jump destinations. 2) Noreturn functions: There's no reliable way to determine which functions are designated by the compiler to be noreturn (either explictly via function attribute, or implicitly via a static function which is a wrapper around a noreturn function.) This information is needed because the code after the call to such a function is optimized out as unreachable and objtool has no way of knowing that. Proposal -------- Add the following new compiler flags which create non-allocatable ELF sections which "annotate" control flow: (Note this is purely hypothetical, intended for starting a discussion. I'm not a compiler person and I haven't written any compiler code.) 1) -fannotate-jump-table Create an .annotate.jump_table section which is an array of the following variable-length structure: struct annotate_jump_table { void *indirect_jmp; long num_targets; void *targets[]; }; For example, given the following switch statement code: .Lswitch_jmp: // %rax is .Lcase_1 or .Lcase_2 jmp %rax .Lcase_1: ... .Lcase_2: ... Add the following code: .pushsection .annotate.jump_table // indirect JMP address .quad .Lswitch_jmp // num jump targets .quad 2 // indirect JMP target addresses .quad .Lcase_1 .quad .Lcase_2 .popsection 2) -fannotate-noreturn Create an .annotate.noreturn section which is an array of pointers to noreturn functions (both explicit/implicit and defined/undefined). For example, given the following three noreturn functions: // explicit noreturn: __attribute__((__noreturn__)) void func1(void) { exit(1); } // explicit noreturn (extern): extern __attribute__((__noreturn__)) void func2(void); // implicit noreturn: static void func3(void) { // call noreturn function func2(); } Add the following code: .pushsection .annotate.noreturn .quad func1 .quad func2 .quad func3 .popsection Alternatives ------------ Another idea which has been floated in the past is for objtool to read DWARF (or .eh_frame) to help it figure out the control flow. That hasn't been tried yet, but would be considerably more difficult and fragile IMO. -- Josh _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel