On Thu, Jan 19, 2023 at 01:22:45PM -0800, Rick Edgecombe wrote: > Subject: Re: [PATCH v5 07/39] x86: Add user control-protection fault handler Subject: x86/shstk: Add... > From: Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> > > A control-protection fault is triggered when a control-flow transfer > attempt violates Shadow Stack or Indirect Branch Tracking constraints. > For example, the return address for a RET instruction differs from the copy > on the shadow stack. ... > diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c > new file mode 100644 > index 000000000000..33d7d119be26 > --- /dev/null > +++ b/arch/x86/kernel/cet.c > @@ -0,0 +1,152 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <linux/ptrace.h> > +#include <asm/bugs.h> > +#include <asm/traps.h> > + > +enum cp_error_code { > + CP_EC = (1 << 15) - 1, That looks like a mask, so CP_EC_MASK I guess. > + > + CP_RET = 1, > + CP_IRET = 2, > + CP_ENDBR = 3, > + CP_RSTRORSSP = 4, > + CP_SETSSBSY = 5, > + > + CP_ENCL = 1 << 15, > +}; ... > +static void do_user_cp_fault(struct pt_regs *regs, unsigned long error_code) > +{ > + struct task_struct *tsk; > + unsigned long ssp; > + > + /* > + * An exception was just taken from userspace. Since interrupts are disabled > + * here, no scheduling should have messed with the registers yet and they > + * will be whatever is live in userspace. So read the SSP before enabling > + * interrupts so locking the fpregs to do it later is not required. > + */ > + rdmsrl(MSR_IA32_PL3_SSP, ssp); > + > + cond_local_irq_enable(regs); > + > + tsk = current; Hmm, should you read current before you enable interrupts? Not that it changes from under us... > + tsk->thread.error_code = error_code; > + tsk->thread.trap_nr = X86_TRAP_CP; > + > + /* Ratelimit to prevent log spamming. */ > + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && > + __ratelimit(&cpf_rate)) { > + pr_emerg("%s[%d] control protection ip:%lx sp:%lx ssp:%lx error:%lx(%s)%s", > + tsk->comm, task_pid_nr(tsk), > + regs->ip, regs->sp, ssp, error_code, > + cp_err_string(error_code), > + error_code & CP_ENCL ? " in enclave" : ""); > + print_vma_addr(KERN_CONT " in ", regs->ip); > + pr_cont("\n"); > + } > + > + force_sig_fault(SIGSEGV, SEGV_CPERR, (void __user *)0); > + cond_local_irq_disable(regs); > +} -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette