diff options
author | Peter Zijlstra <peterz@infradead.org> | 2025-02-13 12:45:47 +0100 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2025-02-14 10:32:07 +0100 |
commit | 882b86fd4e0d49bf91148dbadcdbece19ded40e6 (patch) | |
tree | ba69be9524df4fc5caa67530d871acfe3ad93113 /arch/x86/kernel/cfi.c | |
parent | 306859de59e59f88662b6b56ff2ce3bbb1e375bb (diff) |
x86/ibt: Handle FineIBT in handle_cfi_failure()
Sami reminded me that FineIBT failure does not hook into the regular
CFI failure case, and as such CFI_PERMISSIVE does not work.
Reported-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://lkml.kernel.org/r/20250214092619.GB21726@noisy.programming.kicks-ass.net
Diffstat (limited to 'arch/x86/kernel/cfi.c')
-rw-r--r-- | arch/x86/kernel/cfi.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/arch/x86/kernel/cfi.c b/arch/x86/kernel/cfi.c index e6bf78fac146..f6905bef0af8 100644 --- a/arch/x86/kernel/cfi.c +++ b/arch/x86/kernel/cfi.c @@ -70,11 +70,25 @@ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) unsigned long target; u32 type; - if (!is_cfi_trap(regs->ip)) - return BUG_TRAP_TYPE_NONE; + switch (cfi_mode) { + case CFI_KCFI: + if (!is_cfi_trap(regs->ip)) + return BUG_TRAP_TYPE_NONE; + + if (!decode_cfi_insn(regs, &target, &type)) + return report_cfi_failure_noaddr(regs, regs->ip); + + break; - if (!decode_cfi_insn(regs, &target, &type)) - return report_cfi_failure_noaddr(regs, regs->ip); + case CFI_FINEIBT: + if (!decode_fineibt_insn(regs, &target, &type)) + return BUG_TRAP_TYPE_NONE; + + break; + + default: + return BUG_TRAP_TYPE_NONE; + } return report_cfi_failure(regs, regs->ip, &target, type); } |