All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <kees@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Kees Cook <kees@kernel.org>, Thomas Gleixner <tglx@kernel.org>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Sami Tolvanen <samitolvanen@google.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Bill Wendling <morbo@google.com>,
	Justin Stitt <justinstitt@google.com>,
	x86@kernel.org, llvm@lists.linux.dev,
	linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: [PATCH 1/3] x86/kcfi: Decode the kCFI check from the trap address
Date: Mon, 12 Oct 2026 02:04:24 -0700	[thread overview]
Message-ID: <20261012090436.1676525-1-kees@kernel.org> (raw)
In-Reply-To: <20261012090424.i.497-kees@kernel.org>

Since commit b2250d63e6422 ("x86/kcfi: Optimize call sequence"), a
CONFIG_FINEIBT=y kernel running in kCFI mode rewrites each kCFI call
site at boot so that a failed check traps on the 0xd6 byte of
"test $0xd6, %al", one byte past where the compiler's "ud2" was.
handle_cfi_failure() steps "addr" back one byte to find the trap in
.kcfi_traps, but decode_cfi_insn() still decodes from regs->ip, so it
reads each instruction starting at its second byte.
"movl $-<id>, %r10d" then decodes as "movl $-<id>, %edx", so the
reported type is right by accident, but "addl -15(%r11), %r10d" decodes
as "addl -15(%rbx), %edx", so the reported target is whatever %rbx holds:

  CFI failure at lkdtm_indirect_call+0x16/0x20 (target: 0x12; expected type: 0xc79a2d1b)

Pass the adjusted address to decode_cfi_insn() and decode from it.

Tested ARCH=x86_64 defconfig with CONFIG_CFI=y and CONFIG_LKDTM=y under
QEMU, with LKDTM's CFI_FORWARD_PROTO and both Clang 24.0.0git and GCC
17.0.0 (experimental, with the kCFI series). With CONFIG_FINEIBT=y in
kCFI mode, the report gives %rbx as the target without this change, and
the expected lkdtm_increment_int() with it. With cfi=fineibt, with
cfi=fineibt,paranoid, and with CONFIG_FINEIBT=n, it gives
lkdtm_increment_int() both with and without this change.

Fixes: b2250d63e6422 ("x86/kcfi: Optimize call sequence")
Assisted-by: LLM
Signed-off-by: Kees Cook <kees@kernel.org>
---
 arch/x86/kernel/cfi.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/cfi.c b/arch/x86/kernel/cfi.c
index 1df26dfdce08..8e5c4ed264a0 100644
--- a/arch/x86/kernel/cfi.c
+++ b/arch/x86/kernel/cfi.c
@@ -10,11 +10,11 @@
 #include <asm/insn-eval.h>
 
 /*
- * Returns the target address and the expected type when regs->ip points
+ * Returns the target address and the expected type when addr points
  * to a compiler-generated CFI trap.
  */
-static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
-			    u32 *type)
+static bool decode_cfi_insn(struct pt_regs *regs, unsigned long addr,
+			    unsigned long *target, u32 *type)
 {
 	char buffer[MAX_INSN_SIZE];
 	struct insn insn;
@@ -29,13 +29,13 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
 	 *   movl    -<id>, %r10d       ; 6 bytes
 	 *   addl    -<pos>(%reg), %r10d; 4 bytes
 	 *   je      .Ltmp1             ; 2 bytes
-	 *   ud2                        ; <- regs->ip
+	 *   ud2                        ; <- addr
 	 *   .Ltmp1:
 	 *
 	 * We can decode the expected type and the target address from the
 	 * movl/addl instructions.
 	 */
-	if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 12, MAX_INSN_SIZE))
+	if (copy_from_kernel_nofault(buffer, (void *)addr - 12, MAX_INSN_SIZE))
 		return false;
 	if (insn_decode_kernel(&insn, &buffer[offset]))
 		return false;
@@ -44,7 +44,7 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
 
 	*type = -(u32)insn.immediate.value;
 
-	if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 6, MAX_INSN_SIZE))
+	if (copy_from_kernel_nofault(buffer, (void *)addr - 6, MAX_INSN_SIZE))
 		return false;
 	if (insn_decode_kernel(&insn, &buffer[offset]))
 		return false;
@@ -82,7 +82,7 @@ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
 				return BUG_TRAP_TYPE_NONE;
 		}
 
-		if (!decode_cfi_insn(regs, &target, &type))
+		if (!decode_cfi_insn(regs, addr, &target, &type))
 			return report_cfi_failure_noaddr(regs, addr);
 
 		break;
-- 
2.55.0


  reply	other threads:[~2026-10-12  9:04 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12  9:04 [PATCH 0/3] x86/cfi: Fix a few kCFI issues found with GCC Kees Cook
2026-10-12  9:04 ` Kees Cook [this message]
2026-10-12  9:04 ` [PATCH 2/3] x86/kcfi: Emit the FineIBT paranoid "cs" prefix as a byte Kees Cook
2026-10-12  9:16   ` Peter Zijlstra
2026-10-12 19:05     ` Andrew Cooper
2026-10-13  8:07       ` Kees Cook
2026-10-12  9:04 ` [PATCH 3/3] objtool: Skip jump table jumps in the kCFI indirect call check Kees Cook
2026-10-12  9:22   ` Peter Zijlstra
2026-10-12 18:41     ` Kees Cook
2026-10-13  6:44       ` Peter Zijlstra
2026-10-13  8:37         ` Kees Cook
2026-10-13  9:06           ` Peter Zijlstra
2026-10-13  9:11             ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261012090436.1676525-1-kees@kernel.org \
    --to=kees@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=justinstitt@google.com \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mingo@redhat.com \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=peterz@infradead.org \
    --cc=samitolvanen@google.com \
    --cc=tglx@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.