LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Yu-cheng Yu <yu-cheng.yu@intel.com> To: x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>, Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@redhat.com>, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-api@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>, Andy Lutomirski <luto@kernel.org>, Balbir Singh <bsingharora@gmail.com>, Borislav Petkov <bp@alien8.de>, Cyrill Gorcunov <gorcunov@gmail.com>, Dave Hansen <dave.hansen@linux.intel.com>, Eugene Syromiatnikov <esyr@redhat.com>, Florian Weimer <fweimer@redhat.com>, "H.J. Lu" <hjl.tools@gmail.com>, Jann Horn <jannh@google.com>, Jonathan Corbet <corbet@lwn.net>, Kees Cook <keescook@chromium.org>, Mike Kravetz <mike.kravetz@oracle.com>, Nadav Amit <nadav.amit@gmail.com>, Oleg Nesterov <oleg@redhat.com>, Pavel Machek <pavel@ucw.cz>, Peter Zijlstra <peterz@infradead.org>, Randy Dunlap <rdunlap@infradead.org>, "Ravi V. Shankar" <ravi.v.shankar@intel.com>, Dave Martin <Dave.Martin@arm.com>, Weijiang Yang <weijiang.yang@intel.com>, Pengfei Xu <pengfei.xu@intel.com>, Haitao Huang <haitao.huang@intel.com>, Rick P Edgecombe <rick.p.edgecombe@intel.com> Cc: Yu-cheng Yu <yu-cheng.yu@intel.com>, Michael Kerrisk <mtk.manpages@gmail.com> Subject: [PATCH v30 06/32] x86/cet: Add control-protection fault handler Date: Mon, 30 Aug 2021 11:15:02 -0700 [thread overview] Message-ID: <20210830181528.1569-7-yu-cheng.yu@intel.com> (raw) In-Reply-To: <20210830181528.1569-1-yu-cheng.yu@intel.com> 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; or an indirect JMP instruction, without the NOTRACK prefix, arrives at a non-ENDBR opcode. The control-protection fault handler works in a similar way as the general protection fault handler. It provides the si_code SEGV_CPERR to the signal handler. Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com> Cc: Kees Cook <keescook@chromium.org> Cc: Michael Kerrisk <mtk.manpages@gmail.com> --- v29: - Remove pr_emerg() since it is followed by die(). - Change boot_cpu_has() to cpu_feature_enabled(). v25: - Change CONFIG_X86_CET to CONFIG_X86_SHADOW_STACK. - Change X86_FEATURE_CET to X86_FEATURE_SHSTK. --- arch/x86/include/asm/idtentry.h | 4 ++ arch/x86/kernel/idt.c | 4 ++ arch/x86/kernel/signal_compat.c | 2 +- arch/x86/kernel/traps.c | 62 ++++++++++++++++++++++++++++++ include/uapi/asm-generic/siginfo.h | 3 +- 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index 1345088e9902..a90791433152 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -562,6 +562,10 @@ DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS, exc_stack_segment); DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP, exc_general_protection); DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC, exc_alignment_check); +#ifdef CONFIG_X86_SHADOW_STACK +DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_CP, exc_control_protection); +#endif + /* Raw exception entries which need extra work */ DECLARE_IDTENTRY_RAW(X86_TRAP_UD, exc_invalid_op); DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c index df0fa695bb09..9f1bdaabc246 100644 --- a/arch/x86/kernel/idt.c +++ b/arch/x86/kernel/idt.c @@ -113,6 +113,10 @@ static const __initconst struct idt_data def_idts[] = { #elif defined(CONFIG_X86_32) SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), #endif + +#ifdef CONFIG_X86_SHADOW_STACK + INTG(X86_TRAP_CP, asm_exc_control_protection), +#endif }; /* diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index 06743ec054d2..049ea3dcc6cb 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c @@ -27,7 +27,7 @@ static inline void signal_compat_build_tests(void) */ BUILD_BUG_ON(NSIGILL != 11); BUILD_BUG_ON(NSIGFPE != 15); - BUILD_BUG_ON(NSIGSEGV != 9); + BUILD_BUG_ON(NSIGSEGV != 10); BUILD_BUG_ON(NSIGBUS != 5); BUILD_BUG_ON(NSIGTRAP != 6); BUILD_BUG_ON(NSIGCHLD != 6); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a58800973aed..b64192314a6d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -39,6 +39,7 @@ #include <linux/io.h> #include <linux/hardirq.h> #include <linux/atomic.h> +#include <linux/nospec.h> #include <asm/stacktrace.h> #include <asm/processor.h> @@ -607,6 +608,67 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) cond_local_irq_disable(regs); } +#ifdef CONFIG_X86_SHADOW_STACK +static const char * const control_protection_err[] = { + "unknown", + "near-ret", + "far-ret/iret", + "endbranch", + "rstorssp", + "setssbsy", + "unknown", +}; + +static DEFINE_RATELIMIT_STATE(cpf_rate, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + +/* + * 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) +{ + struct task_struct *tsk; + + if (!user_mode(regs)) { + die("kernel control protection fault", regs, error_code); + panic("Unexpected kernel control protection fault. Machine halted."); + } + + cond_local_irq_enable(regs); + + if (!cpu_feature_enabled(X86_FEATURE_SHSTK)) + 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; + + /* + * Ratelimit to prevent log spamming. + */ + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && + __ratelimit(&cpf_rate)) { + unsigned long ssp; + int cpf_type; + + cpf_type = array_index_nospec(error_code, ARRAY_SIZE(control_protection_err)); + + 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[cpf_type]); + 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); +} +#endif + static bool do_int3(struct pt_regs *regs) { int res; diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index 5a3c221f4c9d..a1a153ea3cc3 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -235,7 +235,8 @@ typedef struct siginfo { #define SEGV_ADIPERR 7 /* Precise MCD exception */ #define SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */ #define SEGV_MTESERR 9 /* Synchronous ARM MTE exception */ -#define NSIGSEGV 9 +#define SEGV_CPERR 10 /* Control protection fault */ +#define NSIGSEGV 10 /* * SIGBUS si_codes -- 2.21.0
next prev parent reply other threads:[~2021-08-30 18:16 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-08-30 18:14 [PATCH v30 00/32] Control-flow Enforcement: Shadow Stack Yu-cheng Yu 2021-08-30 18:14 ` [PATCH v30 01/32] Documentation/x86: Add CET description Yu-cheng Yu 2021-10-05 14:26 ` Dave Hansen 2021-08-30 18:14 ` [PATCH v30 02/32] x86/cet/shstk: Add Kconfig option for Shadow Stack Yu-cheng Yu 2021-08-30 18:14 ` [PATCH v30 03/32] x86/cpufeatures: Add CET CPU feature flags for Control-flow Enforcement Technology (CET) Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 04/32] x86/cpufeatures: Introduce CPU setup and option parsing for CET Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 05/32] x86/fpu/xstate: Introduce CET MSR and XSAVES supervisor states Yu-cheng Yu 2021-08-30 18:15 ` Yu-cheng Yu [this message] 2021-08-30 18:15 ` [PATCH v30 07/32] x86/mm: Remove _PAGE_DIRTY from kernel RO pages Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 08/32] x86/mm: Move pmd_write(), pud_write() up in the file Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 09/32] x86/mm: Introduce _PAGE_COW Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 10/32] drm/i915/gvt: Change _PAGE_DIRTY to _PAGE_DIRTY_BITS Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 11/32] x86/mm: Update pte_modify for _PAGE_COW Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 12/32] x86/mm: Update ptep_set_wrprotect() and pmdp_set_wrprotect() for transition from _PAGE_DIRTY to _PAGE_COW Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 13/32] mm: Move VM_UFFD_MINOR_BIT from 37 to 38 Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 14/32] mm: Introduce VM_SHADOW_STACK for shadow stack memory Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 15/32] x86/mm: Check Shadow Stack page fault errors Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 16/32] x86/mm: Update maybe_mkwrite() for shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 17/32] mm: Fixup places that call pte_mkwrite() directly Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 18/32] mm: Add guard pages around a shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 19/32] mm/mmap: Add shadow stack pages to memory accounting Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 20/32] mm: Update can_follow_write_pte() for shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 21/32] mm/mprotect: Exclude shadow stack from preserve_write Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 22/32] mm: Re-introduce vm_flags to do_mmap() Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 23/32] x86/cet/shstk: Add user-mode shadow stack support Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 24/32] x86/process: Change copy_thread() argument 'arg' to 'stack_size' Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 25/32] x86/cet/shstk: Handle thread shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 26/32] x86/cet/shstk: Introduce shadow stack token setup/verify routines Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 27/32] x86/cet/shstk: Handle signals for shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 28/32] ELF: Introduce arch_setup_elf_property() Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 29/32] x86/cet/shstk: Add arch_prctl functions for shadow stack Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 30/32] mm: Move arch_calc_vm_prot_bits() to arch/x86/include/asm/mman.h Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 31/32] mm: Update arch_validate_flags() to test vma anonymous Yu-cheng Yu 2021-08-30 18:15 ` [PATCH v30 32/32] mm: Introduce PROT_SHADOW_STACK for shadow stack Yu-cheng Yu
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=20210830181528.1569-7-yu-cheng.yu@intel.com \ --to=yu-cheng.yu@intel.com \ --cc=Dave.Martin@arm.com \ --cc=arnd@arndb.de \ --cc=bp@alien8.de \ --cc=bsingharora@gmail.com \ --cc=corbet@lwn.net \ --cc=dave.hansen@linux.intel.com \ --cc=esyr@redhat.com \ --cc=fweimer@redhat.com \ --cc=gorcunov@gmail.com \ --cc=haitao.huang@intel.com \ --cc=hjl.tools@gmail.com \ --cc=hpa@zytor.com \ --cc=jannh@google.com \ --cc=keescook@chromium.org \ --cc=linux-api@vger.kernel.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-doc@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=luto@kernel.org \ --cc=mike.kravetz@oracle.com \ --cc=mingo@redhat.com \ --cc=mtk.manpages@gmail.com \ --cc=nadav.amit@gmail.com \ --cc=oleg@redhat.com \ --cc=pavel@ucw.cz \ --cc=pengfei.xu@intel.com \ --cc=peterz@infradead.org \ --cc=ravi.v.shankar@intel.com \ --cc=rdunlap@infradead.org \ --cc=rick.p.edgecombe@intel.com \ --cc=tglx@linutronix.de \ --cc=weijiang.yang@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: linkBe 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; as well as URLs for NNTP newsgroup(s).