Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2321325imm; Thu, 7 Jun 2018 08:45:03 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLbh8q0UcCe8GA5ft1fA1bJ5kdURuapyqERC1XBWbDHGHT8A/x5fQ3XkLuycOXA2e64rysb X-Received: by 2002:a17:902:b494:: with SMTP id y20-v6mr2540332plr.136.1528386303433; Thu, 07 Jun 2018 08:45:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528386303; cv=none; d=google.com; s=arc-20160816; b=WqitjwHSjPLrjTuUbzmqkgv0NArbwOcaMaT0cU4Veh8TffW2IZUlq9r9cr/T9oSK4i Jit4Epck9DBROaqbfV81sTBhRl/+4DoZ4G1HbQdZpmU8c07RxhvWJ/KqhE/XjerBPVOQ PX6xd3zQcRckFkMc9Qhw4UXIvlJxkRjJfL9wpRmt3nYA2/SK7G0n/RD/I+K1p9dGTkjD Tgco8x5bvrI2XQ9tO3N8sUrQu6TOdfXHI2zMF/WvdabSXUyaUlaPoaf1x7FQnWFLU1ig V/jMjL+R5jMM6PJFX6UXEindDSOvJbLFZje+k6K9bBhnj/PqKBQ2PnpxK5So5qo/rihN fh+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=azhXthczPx1/TLI/24IhtL4QoH0M6TWz1dZSG4h69Qg=; b=s+u/flnn/Iu5C6r/BgYpBSq1Ccs4PkcifXExHbzBi1OH7kFE69pcnIMrq06qJhr8sH VwZ/W+Z7GMACEG27AhW6mX9V/oTPinDNKKjm3fruy5RhDiCiVOo0YYmfn2zjMpK0WRrr i/kHNdVjs03SHXmTf1rapoOStug9/zMnFLllf+Q/rKNvoIZ+B9OBIgglBtfwb0YhvdFB 0tC0s3wP+st3+xd0N1iQ1M3LDvGDZdtny/Mj01PpjV7cV+21WmeOjzarCtRVzMtOShTW pA82/ssvUIPOrwzw+KH9zWwGTYNmzIxXVZ8bQoYZTGD+FD8NplEe5pMTlj63W1tnKVqJ Mq/w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w187-v6si25924002pgb.11.2018.06.07.08.44.49; Thu, 07 Jun 2018 08:45:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935433AbeFGPmu (ORCPT + 99 others); Thu, 7 Jun 2018 11:42:50 -0400 Received: from mga09.intel.com ([134.134.136.24]:36344 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934587AbeFGOlb (ORCPT ); Thu, 7 Jun 2018 10:41:31 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Jun 2018 07:41:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,486,1520924400"; d="scan'208";a="62632621" Received: from 2b52.sc.intel.com ([143.183.136.51]) by orsmga001.jf.intel.com with ESMTP; 07 Jun 2018 07:41:29 -0700 From: Yu-cheng Yu To: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , "H.J. Lu" , Vedvyas Shanbhogue , "Ravi V. Shankar" , Dave Hansen , Andy Lutomirski , Jonathan Corbet , Oleg Nesterov , Arnd Bergmann , Mike Kravetz Cc: Yu-cheng Yu Subject: [PATCH 02/10] x86/cet: Introduce WRUSS instruction Date: Thu, 7 Jun 2018 07:37:59 -0700 Message-Id: <20180607143807.3611-3-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180607143807.3611-1-yu-cheng.yu@intel.com> References: <20180607143807.3611-1-yu-cheng.yu@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org WRUSS is a new kernel-mode instruction but writes directly to user shadow stack memory. This is used to construct a return address on the shadow stack for the signal handler. This instruction can fault if the user shadow stack is invalid shadow stack memory. In that case, the kernel does fixup. Signed-off-by: Yu-cheng Yu --- arch/x86/include/asm/special_insns.h | 44 +++++++++++++++++++++++++++ arch/x86/lib/x86-opcode-map.txt | 2 +- arch/x86/mm/fault.c | 13 +++++++- tools/objtool/arch/x86/lib/x86-opcode-map.txt | 2 +- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 317fc59b512c..8ce532fcc171 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -237,6 +237,50 @@ static inline void clwb(volatile void *__p) : [pax] "a" (p)); } +#ifdef CONFIG_X86_INTEL_CET + +#if defined(CONFIG_IA32_EMULATION) || defined(CONFIG_X86_X32) +static inline int write_user_shstk_32(unsigned long addr, unsigned int val) +{ + int err; + + asm volatile("1:.byte 0x66, 0x0f, 0x38, 0xf5, 0x37\n" + "xor %[err],%[err]\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: mov $-1,%[err]; jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) + : [err] "=a" (err) + : [val] "S" (val), [addr] "D" (addr) + : "memory"); + return err; +} +#else +static inline int write_user_shstk_32(unsigned long addr, unsigned int val) +{ + return 0; +} +#endif + +static inline int write_user_shstk_64(unsigned long addr, unsigned long val) +{ + int err; + + asm volatile("1:.byte 0x66, 0x48, 0x0f, 0x38, 0xf5, 0x37\n" + "xor %[err],%[err]\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: mov $-1,%[err]; jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) + : [err] "=a" (err) + : [val] "S" (val), [addr] "D" (addr) + : "memory"); + return err; +} +#endif /* CONFIG_X86_INTEL_CET */ + #define nop() asm volatile ("nop") diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt index e0b85930dd77..72bb7c48a7df 100644 --- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt @@ -789,7 +789,7 @@ f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v) f3: Grp17 (1A) -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) +f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | WRUSS Pq,Qq (66),REX.W f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) EndTable diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 2b3b9170109c..f157338862f8 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -640,6 +640,17 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) return 0; } +/* + * WRUSS is a kernel instrcution and but writes to user + * shadow stack memory. When a fault occurs, both + * X86_PF_USER and X86_PF_SHSTK are set. + */ +static int is_wruss(struct pt_regs *regs, unsigned long error_code) +{ + return (((error_code & (X86_PF_USER | X86_PF_SHSTK)) == + (X86_PF_USER | X86_PF_SHSTK)) && !user_mode(regs)); +} + static const char nx_warning[] = KERN_CRIT "kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n"; static const char smep_warning[] = KERN_CRIT @@ -851,7 +862,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, struct task_struct *tsk = current; /* User mode accesses just cause a SIGSEGV */ - if (error_code & X86_PF_USER) { + if ((error_code & X86_PF_USER) && !is_wruss(regs, error_code)) { /* * It's possible to have interrupts off here: */ diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt index e0b85930dd77..72bb7c48a7df 100644 --- a/tools/objtool/arch/x86/lib/x86-opcode-map.txt +++ b/tools/objtool/arch/x86/lib/x86-opcode-map.txt @@ -789,7 +789,7 @@ f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v) f3: Grp17 (1A) -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) +f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | WRUSS Pq,Qq (66),REX.W f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) EndTable -- 2.15.1