Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2211223imm; Tue, 10 Jul 2018 15:33:05 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfWYuWJYwN/1zkJX9z+WKlr5xXX+NvgtN8HYLUjd+aSZVppev+dOcGHYxM+Wm3FNZ6T4RVy X-Received: by 2002:a17:902:a989:: with SMTP id bh9-v6mr26857269plb.245.1531261985914; Tue, 10 Jul 2018 15:33:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531261985; cv=none; d=google.com; s=arc-20160816; b=uYpeW6lXTO0mqWvdpE/xYb3Tlii4a7hkfYdnVtg4dtSTWEjdWbxEFe1DHfdhsSG3Jn UPasBS1IYpzTdPGpxz5FxcVkxQUqSGuOE9brdCRhwg4mZ7pAhBAAjqlR6sAp+Kc9O1bJ yzLDEoBbQd2Gf7li/jbiWjwNu2HMaA2ZzJkJcimwj9uEaSCGW9MUDs9bZ2gG6d39A3ra AmUy0e7m5oZzGImXDPTiR30yn79zk/Jazocqfbn6y16ohdq8Tyxy5yBjxZlBdC6FEaMg FDX8MJTrJl8R76crQmKxqunWD896rxWVjMEhPYXIgdjhuWLPRCHpNRDnqxOJfTzkRT2d /CSg== 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=qfSaaP094Ub41esZ4AtIQhLfQCRyFtmoNLIOOdhRJD8=; b=jx1wiJLeMqSe4NzHQh14KD09/DwKoYkw1hEjXe6AHessm/qXp6qkGJ4g9vyN8H7XXD omqowTRT9K4zGX4FPF4Hkzy0lneKBpGgeVvCTE7XrbDnXd1I26WQCQ6Vp1eoNiZsoW1P g0hRusJ3MKFISQrfRUXpgxiqaHdZhbQiTgRj+fjJhxdnU/kgW3kS6kaY6WFn0GaMRjCv U5ODXde/CcqBsZ2jISuQoY5ir/o84n1O77ci0w5q6cqoxC751AYUz9N4zOWdVSxleQ28 CZ+hykLa7NvBkNG9ClUkPGaZ7WjyNQTHtu7vvfa63qqLS34GutctLWpzp4V6C/H97atj Nl2Q== 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 h29-v6si16947244pgb.53.2018.07.10.15.32.50; Tue, 10 Jul 2018 15:33:05 -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 S1732538AbeGJWc2 (ORCPT + 99 others); Tue, 10 Jul 2018 18:32:28 -0400 Received: from mga12.intel.com ([192.55.52.136]:33776 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732408AbeGJWc0 (ORCPT ); Tue, 10 Jul 2018 18:32:26 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Jul 2018 15:31:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,335,1526367600"; d="scan'208";a="70305434" Received: from 2b52.sc.intel.com ([143.183.136.52]) by fmsmga004.fm.intel.com with ESMTP; 10 Jul 2018 15:31:15 -0700 From: Yu-cheng Yu To: x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , 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 , Andy Lutomirski , Balbir Singh , Cyrill Gorcunov , Dave Hansen , Florian Weimer , "H.J. Lu" , Jann Horn , Jonathan Corbet , Kees Cook , Mike Kravetz , Nadav Amit , Oleg Nesterov , Pavel Machek , Peter Zijlstra , "Ravi V. Shankar" , Vedvyas Shanbhogue Cc: Yu-cheng Yu Subject: [RFC PATCH v2 18/27] x86/cet/shstk: Introduce WRUSS instruction Date: Tue, 10 Jul 2018 15:26:30 -0700 Message-Id: <20180710222639.8241-19-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180710222639.8241-1-yu-cheng.yu@intel.com> References: <20180710222639.8241-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 | 45 +++++++++++++++++++ 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, 59 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 317fc59b512c..c69d8d6b457f 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -237,6 +237,51 @@ 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: wrussd %[val], (%[addr])\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)); + + return err; +} +#else +static inline int write_user_shstk_32(unsigned long addr, unsigned int val) +{ + BUG(); + return 0; +} +#endif + +static inline int write_user_shstk_64(unsigned long addr, unsigned long val) +{ + int err = 0; + + asm volatile("1: wrussq %[val], (%[addr])\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)); + + 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 fcd5739151f9..92f178b8b598 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -641,6 +641,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 void show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long address) @@ -848,7 +859,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.17.1