From nobody Mon Feb 9 13:36:02 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0FBC9EB64D8 for ; Thu, 22 Jun 2023 14:51:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231974AbjFVOvC (ORCPT ); Thu, 22 Jun 2023 10:51:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231881AbjFVOug (ORCPT ); Thu, 22 Jun 2023 10:50:36 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BACD19B7 for ; Thu, 22 Jun 2023 07:50:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:References: Subject:Cc:To:From:Date:Message-ID:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:In-Reply-To; bh=QJieZYDWzFCRvSf0wOeMBiP6eKWnKstpX1vra/Nb2RE=; b=t5FAyWdSCA8MhmTF70mRlJ8+bF PtTAVofzOV0VUJ4IiR6Mj3h2bermXWeNMQu6CTVlEUAHj7O9WATPVBktgOnDycDJWu9ZAh6nY7JXL Kci/BqJJMsb5tUV3YqtNL2Q/x7x0IZFV0DMecRpsvSf127dAPsa0FsRHtSaRyTX6RVBa49KwKbFkU f5rNyS8G8XvzWrM82W1/Q2pUh6uZ7SSeSYKMOKNY9ugxyEXvyyV/d2AZHHsChCjBAMmsdYuasMPTp Vl5cd+fqKKEiEuTe9gWblRPAtTOjqmUdvLcptOBXcBHu2oGQxRO2B6ohEXYnT7IbnHN/4TQrCzJnr kwc3bnog==; Received: from j130084.upc-j.chello.nl ([24.132.130.84] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1qCLdh-00FgfC-Ru; Thu, 22 Jun 2023 14:50:26 +0000 Received: from hirez.programming.kicks-ass.net (hirez.programming.kicks-ass.net [192.168.1.225]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by noisy.programming.kicks-ass.net (Postfix) with ESMTPS id 3390C3006D5; Thu, 22 Jun 2023 16:50:24 +0200 (CEST) Received: by hirez.programming.kicks-ass.net (Postfix, from userid 0) id 1C78A209D8B3D; Thu, 22 Jun 2023 16:50:24 +0200 (CEST) Message-ID: <20230622144321.494426891@infradead.org> User-Agent: quilt/0.66 Date: Thu, 22 Jun 2023 16:42:21 +0200 From: Peter Zijlstra To: x86@kernel.org, alyssa.milburn@linux.intel.com Cc: linux-kernel@vger.kernel.org, peterz@infradead.org, samitolvanen@google.com, keescook@chromium.org, jpoimboe@kernel.org, joao@overdrivepizza.com, brgerst@gmail.com Subject: [PATCH v2 3/6] x86/cfi: Extend ENDBR sealing to kCFI References: <20230622144218.860926475@infradead.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Kees noted that IBT sealing could be extended to kCFI. Fundamentally it is the list of functions that do not have their address taken and are thus never called indirectly. It doesn't matter that objtool uses IBT infrastructure to determine this list, once we have it it can also be used to clobber kCFI hashes and seal kCFI indirect calls. Suggested-by: Kees Cook Signed-off-by: Peter Zijlstra (Intel) --- arch/x86/kernel/alternative.c | 44 +++++++++++++++++++++++++++++++++++++= ++++- 1 file changed, 43 insertions(+), 1 deletion(-) --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -778,6 +778,8 @@ void __init_or_module noinline apply_ret =20 #ifdef CONFIG_X86_KERNEL_IBT =20 +static void poison_cfi(void *addr); + static void __init_or_module poison_endbr(void *addr, bool warn) { u32 endbr, poison =3D gen_endbr_poison(); @@ -802,6 +804,9 @@ static void __init_or_module poison_endb =20 /* * Generated by: objtool --ibt + * + * Seal the functions for indirect calls by clobbering the ENDBR instructi= ons + * and the kCFI hash value. */ void __init_or_module noinline apply_seal_endbr(s32 *start, s32 *end) { @@ -812,7 +817,7 @@ void __init_or_module noinline apply_sea =20 poison_endbr(addr, true); if (IS_ENABLED(CONFIG_FINEIBT)) - poison_endbr(addr - 16, false); + poison_cfi(addr - 16); } } =20 @@ -1177,6 +1182,41 @@ static void __apply_fineibt(s32 *start_r pr_err("Something went horribly wrong trying to rewrite the CFI implement= ation.\n"); } =20 +static inline void poison_hash(void *addr) +{ + *(u32 *)addr =3D 0; +} + +static void poison_cfi(void *addr) +{ + switch (cfi_mode) { + case CFI_FINEIBT: + /* + * __cfi_\func: + * osp nopl (%rax) + * subl $0, %r10d + * jz 1f + * ud2 + * 1: nop + */ + poison_endbr(addr, false); + poison_hash(addr + fineibt_preamble_hash); + break; + + case CFI_KCFI: + /* + * __cfi_\func: + * movl $0, %eax + * .skip 11, 0x90 + */ + poison_hash(addr + 1); + break; + + default: + break; + } +} + #else =20 static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, @@ -1184,6 +1224,8 @@ static void __apply_fineibt(s32 *start_r { } =20 +static void poison_cfi(void *addr) { } + #endif =20 void apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,