On 2/4/2021 12:09 PM, Kees Cook wrote:
On Wed, Feb 03, 2021 at 02:55:28PM -0800, Yu-cheng Yu wrote:

[...]

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 7f5aec758f0e..f5354c35df32 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -606,6 +606,66 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
        cond_local_irq_disable(regs);
  }
+#ifdef CONFIG_X86_CET
+static const char * const control_protection_err[] = {
+       "unknown",
+       "near-ret",
+       "far-ret/iret",
+       "endbranch",
+       "rstorssp",
+       "setssbsy",
+};
+
+/*
+ * When a control protection exception occurs, send a signal to the responsible
+ * application.  Currently, control protection is only enabled for user mode.
+ * This exception should not come from kernel mode.
+ */
+DEFINE_IDTENTRY_ERRORCODE(exc_control_protection)
+{
+       static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+                                     DEFAULT_RATELIMIT_BURST);
+       struct task_struct *tsk;
+
+       if (!user_mode(regs)) {
+               pr_emerg("PANIC: unexpected kernel control protection fault\n");
+               die("kernel control protection fault", regs, error_code);
+               panic("Machine halted.");
+       }
+
+       cond_local_irq_enable(regs);
+
+       if (!boot_cpu_has(X86_FEATURE_CET))
+               WARN_ONCE(1, "Control protection fault with CET support 
disabled\n");
+
+       tsk = current;
+       tsk->thread.error_code = error_code;
+       tsk->thread.trap_nr = X86_TRAP_CP;
+
+       if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+           __ratelimit(&rs)) {
+               unsigned int max_err;
+               unsigned long ssp;
+
+               max_err = ARRAY_SIZE(control_protection_err) - 1;
+               if (error_code < 0 || error_code > max_err)
+                       error_code = 0;

Do you want to mask the error_code here before printing its value?

+
+               rdmsrl(MSR_IA32_PL3_SSP, ssp);
+               pr_emerg("%s[%d] control protection ip:%lx sp:%lx ssp:%lx 
error:%lx(%s)",
+                        tsk->comm, task_pid_nr(tsk),
+                        regs->ip, regs->sp, ssp, error_code,
+                        control_protection_err[error_code]);

Instead, you could clamp error_code to ARRAY_SIZE(control_protection_err),
and add another "unknown" to the end of the strings:

        control_protection_err[
                array_index_nospec(error_code,
                                   ARRAY_SIZE(control_protection_err))]

Everything else looks good.


I will update it.  Thanks!

[...]

Reply via email to