From: Peter Zijlstra <peterz@infradead.org>
To: Kees Cook <kees@kernel.org>
Cc: x86@kernel.org, linux-kernel@vger.kernel.org,
alyssa.milburn@intel.com, scott.d.constable@intel.com,
joao@overdrivepizza.com, andrew.cooper3@citrix.com,
jpoimboe@kernel.org, jose.marchesi@oracle.com,
hjl.tools@gmail.com, ndesaulniers@google.com,
samitolvanen@google.com, nathan@kernel.org, ojeda@kernel.org,
alexei.starovoitov@gmail.com, mhiramat@kernel.org, jmill@asu.edu
Subject: Re: [PATCH v3 06/10] x86/traps: Decode LOCK Jcc.d8 #UD
Date: Wed, 19 Feb 2025 20:44:41 +0100 [thread overview]
Message-ID: <20250219194441.GA28384@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20250219183329.GE23004@noisy.programming.kicks-ass.net>
On Wed, Feb 19, 2025 at 07:33:30PM +0100, Peter Zijlstra wrote:
> On Wed, Feb 19, 2025 at 10:20:25AM -0800, Kees Cook wrote:
>
> > I realize these are misplaced chunks, but passing ud_type into the
> > handler feels like a layering violation to me. I struggled with this
> > when making recommendations for the UBSAN handler too, so I'm not sure
> > I have any better idea. It feels like there should be a way to separate
> > this logic more cleanly. The handlers are all doing very similar things:
> >
> > 1- find the address where a bad thing happened
> > 2- report about it
> > 3- whether to continue execution
> > 4- where to continue execution
> >
> > The variability happens with 1 and 4, where it depends on the instruction
> > sequences. Meh, I dunno. I can't see anything cleaner, so passing down
> > ud_type does seem best.
>
> Yeah, agreed. I couldn't get rid of relying on ud_type entirely (it was
> worse), I'll see if I can come up something.
Completely untested, but I think it should work...
diff --git a/arch/x86/include/asm/cfi.h b/arch/x86/include/asm/cfi.h
index 896cf8cf4ea7..2f6a01f098b5 100644
--- a/arch/x86/include/asm/cfi.h
+++ b/arch/x86/include/asm/cfi.h
@@ -109,7 +109,7 @@ extern bhi_thunk __bhi_args_end[];
struct pt_regs;
#ifdef CONFIG_CFI_CLANG
-enum bug_trap_type handle_cfi_failure(int ud_type, struct pt_regs *regs);
+enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
#define __bpfcall
extern u32 cfi_bpf_hash;
extern u32 cfi_bpf_subprog_hash;
@@ -133,10 +133,10 @@ extern u32 cfi_get_func_hash(void *func);
extern int cfi_get_func_arity(void *func);
#ifdef CONFIG_FINEIBT
-extern bool decode_fineibt_insn(int ud_type, struct pt_regs *regs, unsigned long *target, u32 *type);
+extern bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type);
#else
static inline bool
-decode_fineibt_insn(int ud_type, struct pt_regs *regs, unsigned long *target, u32 *type)
+decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)
{
return false;
}
@@ -144,7 +144,7 @@ decode_fineibt_insn(int ud_type, struct pt_regs *regs, unsigned long *target, u3
#endif
#else
-static inline enum bug_trap_type handle_cfi_failure(int ud_type, struct pt_regs *regs)
+static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
return BUG_TRAP_TYPE_NONE;
}
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 5bf5c0283259..d00eabf092f2 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -1631,7 +1631,7 @@ static void poison_cfi(void *addr)
* We check the preamble by checking for the ENDBR instruction relative to the
* 0xEA instruction.
*/
-static bool decode_fineibt_preamble(int ud_type, struct pt_regs *regs,
+static bool decode_fineibt_preamble(struct pt_regs *regs,
unsigned long *target, u32 *type)
{
unsigned long addr = regs->ip - fineibt_preamble_ud;
@@ -1660,7 +1660,7 @@ static bool decode_fineibt_preamble(int ud_type, struct pt_regs *regs,
/*
* regs->ip points to one of the UD2 in __bhi_args[].
*/
-static bool decode_fineibt_bhi(int ud_type, struct pt_regs *regs,
+static bool decode_fineibt_bhi(struct pt_regs *regs,
unsigned long *target, u32 *type)
{
unsigned long addr;
@@ -1696,12 +1696,15 @@ static bool decode_fineibt_bhi(int ud_type, struct pt_regs *regs,
* regs->ip points to a LOCK Jcc.d8 instruction from the fineibt_paranoid_start[]
* sequence.
*/
-static bool decode_fineibt_paranoid(int ud_type, struct pt_regs *regs,
+static bool decode_fineibt_paranoid(struct pt_regs *regs,
unsigned long *target, u32 *type)
{
unsigned long addr = regs->ip - fineibt_paranoid_ud;
u32 hash;
+ if (!is_cfi_trap(addr + fineibt_caller_size - LEN_UD2))
+ return false;
+
__get_kernel_nofault(&hash, addr + fineibt_caller_hash, u32, Efault);
*target = regs->r11 + fineibt_preamble_size;
*type = regs->r10;
@@ -1716,15 +1719,17 @@ static bool decode_fineibt_paranoid(int ud_type, struct pt_regs *regs,
return false;
}
-bool decode_fineibt_insn(int ud_type, struct pt_regs *regs,
+bool decode_fineibt_insn(struct pt_regs *regs,
unsigned long *target, u32 *type)
{
- if (ud_type == BUG_LOCK)
- return decode_fineibt_paranoid(ud_type, regs, target, type);
if (regs->ip > (unsigned long)__bhi_args &&
regs->ip < (unsigned long)__bhi_args_end)
- return decode_fineibt_bhi(ud_type, regs, target, type);
- return decode_fineibt_preamble(ud_type, regs, target, type);
+ return decode_fineibt_bhi(regs, target, type);
+
+ if (decode_fineibt_paranoid(regs, target, type))
+ return true;
+
+ return decode_fineibt_preamble(regs, target, type);
}
#else
diff --git a/arch/x86/kernel/cfi.c b/arch/x86/kernel/cfi.c
index a1b03255f4b9..77086cf565ec 100644
--- a/arch/x86/kernel/cfi.c
+++ b/arch/x86/kernel/cfi.c
@@ -65,7 +65,7 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
* Checks if a ud2 trap is because of a CFI failure, and handles the trap
* if needed. Returns a bug_trap_type value similarly to report_bug.
*/
-enum bug_trap_type handle_cfi_failure(int ud_type, struct pt_regs *regs)
+enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
unsigned long target, addr = regs->ip;
u32 type;
@@ -81,7 +81,7 @@ enum bug_trap_type handle_cfi_failure(int ud_type, struct pt_regs *regs)
break;
case CFI_FINEIBT:
- if (!decode_fineibt_insn(ud_type, regs, &target, &type))
+ if (!decode_fineibt_insn(regs, &target, &type))
return BUG_TRAP_TYPE_NONE;
break;
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 67fa578c451b..8945e3e23240 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -333,21 +333,18 @@ static noinstr bool handle_bug(struct pt_regs *regs)
raw_local_irq_enable();
switch (ud_type) {
- case BUG_EA:
- case BUG_LOCK:
- if (handle_cfi_failure(ud_type, regs) == BUG_TRAP_TYPE_WARN) {
- if (regs->ip == addr)
- regs->ip += ud_len;
+ case BUG_UD2:
+ if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN ) {
handled = true;
+ break;
}
- break;
+ fallthrough;
- case BUG_UD2:
- if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN ||
- handle_cfi_failure(ud_type, regs) == BUG_TRAP_TYPE_WARN) {
- if (regs->ip == addr)
- regs->ip += ud_len;
+ case BUG_EA:
+ case BUG_LOCK:
+ if (handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) {
handled = true;
+ break;
}
break;
@@ -363,6 +360,10 @@ static noinstr bool handle_bug(struct pt_regs *regs)
break;
}
+ /* Continue after the trapping instruction, unless overridden. */
+ if (handled && regs->ip == addr)
+ regs->ip += ud_len;
+
/* Restore failure location if we're not continuing execution. */
if (!handled && regs->ip != addr)
regs->ip = addr;
next prev parent reply other threads:[~2025-02-19 19:44 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-19 16:21 [PATCH v3 00/10] x86/ibt: FineIBT-BHI Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 01/10] x86/cfi: Add warn option Peter Zijlstra
2025-02-19 17:50 ` Kees Cook
2025-02-19 17:56 ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 02/10] x86/ibt: Add exact_endbr() helper Peter Zijlstra
2025-02-19 17:51 ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 03/10] x86/traps: Decode 0xEA #UD Peter Zijlstra
2025-02-19 16:47 ` Andrew Cooper
2025-02-19 16:49 ` Peter Zijlstra
2025-02-19 17:52 ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 04/10] x86/traps: Allow custom fixups in handle_bug() Peter Zijlstra
2025-02-19 17:55 ` Kees Cook
2025-02-19 18:17 ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 05/10] x86/ibt: Optimize FineIBT sequence Peter Zijlstra
2025-02-19 17:15 ` Andrew Cooper
2025-02-20 18:28 ` Constable, Scott D
2025-02-19 18:01 ` Kees Cook
2025-02-19 18:18 ` Peter Zijlstra
2025-02-19 18:23 ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 06/10] x86/traps: Decode LOCK Jcc.d8 #UD Peter Zijlstra
2025-02-19 16:45 ` Peter Zijlstra
2025-02-19 18:20 ` Kees Cook
2025-02-19 18:33 ` Peter Zijlstra
2025-02-19 19:44 ` Peter Zijlstra [this message]
2025-02-19 16:21 ` [PATCH v3 07/10] x86/ibt: Add paranoid FineIBT mode Peter Zijlstra
2025-02-19 17:31 ` Andrew Cooper
2025-02-19 20:07 ` Peter Zijlstra
2025-02-21 13:40 ` David Laight
2025-02-19 18:05 ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 08/10] x86: BHI stubs Peter Zijlstra
2025-02-19 18:07 ` Kees Cook
2025-02-19 18:07 ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 09/10] x86/ibt: Implement FineIBT-BHI mitigation Peter Zijlstra
2025-02-19 18:11 ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 10/10] x86/ibt: Optimize fineibt-bhi arity 1 case Peter Zijlstra
2025-02-19 18:21 ` Kees Cook
2025-02-19 17:36 ` [PATCH v3 00/10] x86/ibt: FineIBT-BHI Kees Cook
2025-02-20 11:27 ` 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=20250219194441.GA28384@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=alexei.starovoitov@gmail.com \
--cc=alyssa.milburn@intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=hjl.tools@gmail.com \
--cc=jmill@asu.edu \
--cc=joao@overdrivepizza.com \
--cc=jose.marchesi@oracle.com \
--cc=jpoimboe@kernel.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=ojeda@kernel.org \
--cc=samitolvanen@google.com \
--cc=scott.d.constable@intel.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox