summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/cfi.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2025-02-13 12:45:47 +0100
committerPeter Zijlstra <peterz@infradead.org>2025-02-14 10:32:07 +0100
commit882b86fd4e0d49bf91148dbadcdbece19ded40e6 (patch)
treeba69be9524df4fc5caa67530d871acfe3ad93113 /arch/x86/kernel/cfi.c
parent306859de59e59f88662b6b56ff2ce3bbb1e375bb (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.c22
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);
}