Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp778422imm; Fri, 21 Sep 2018 08:09:48 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaQTlXUYZaEC/evfwrCOeMALwYvSMjtNF0dfjQxIkhqxeKYwn+vXT/URCSJxJTkQe+v/JfV X-Received: by 2002:a63:3cc:: with SMTP id 195-v6mr3519577pgd.262.1537542588817; Fri, 21 Sep 2018 08:09:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537542588; cv=none; d=google.com; s=arc-20160816; b=ExgimIjmsYql1JhrTrYSdmdtco+yRjVJYG8/9JAdjIh7qnkO1A6aZ23frMI0uW4b8X +PYsiyeDv12Uoe20mRqq/+Eg44J/d3vWBmjXRJdLGSMY8yORDVtH7SdwPxFeHsBXLyEp TUqU7cXDcWJRCaqUUbFL0iYilzkyoL3+WRICTp93thIdc2H/yzf9hSXPEgeY1hibP16C AobQXK0ym3JMijpQIN3whJjA2cc+VY6+w3Swr4umB+HlSUeJD8YsBP8vjPHBuaBxaewu 5Rz8MU/BkUcKKTAsBFYZuIc5yrjEjax3u+JmfWDeko1VtaZbvoIl0fBua2t/fW0AyS0U a/DQ== 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; bh=vXXsumCCPQu82rm5dgLsDNuf4LdMeyXLOXjYtSFPX3E=; b=kwIILUM56qQF1+QTeMi5KrN52gpk9zf1ieT0hToQvie4QHZ0c5H13AUKed/iZWEC0t B9t3DqYv40mcil3XGC9cKgNaThDAkB7YirtKWT35i/OuXUfSn5GIjQK4ZkpLJ0yYhLN7 9YBhuQFM1fmMFbHx/uS5PIlo/bsKhdm2Ayg4rgbJ8LzO2aP7fRazlSjB7B0VUPj66Vbt Wet5CgFbtZkcbFm/V52EUaF5fz5Y+eIQSA3SIvKYIgo48HyTnwZ1brNkPW1pFUCGM6vg uCJV5wJrHwwviH2YYrJ+xxh+OaCUKiIPDw8lU94WxHg6VV/N3pzNa+//NZBnxpe0opRa F3fA== 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 f62-v6si30062894pfb.218.2018.09.21.08.09.32; Fri, 21 Sep 2018 08:09:48 -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 S2390516AbeIUU6K (ORCPT + 99 others); Fri, 21 Sep 2018 16:58:10 -0400 Received: from mga11.intel.com ([192.55.52.93]:13568 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390450AbeIUU6I (ORCPT ); Fri, 21 Sep 2018 16:58:08 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Sep 2018 08:08:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,285,1534834800"; d="scan'208";a="71856587" Received: from 2b52.sc.intel.com ([143.183.136.51]) by fmsmga007.fm.intel.com with ESMTP; 21 Sep 2018 08:08:50 -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 , Randy Dunlap , "Ravi V. Shankar" , Vedvyas Shanbhogue Cc: Yu-cheng Yu Subject: [RFC PATCH v4 19/27] x86/cet/shstk: Introduce WRUSS instruction Date: Fri, 21 Sep 2018 08:03:43 -0700 Message-Id: <20180921150351.20898-20-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180921150351.20898-1-yu-cheng.yu@intel.com> References: <20180921150351.20898-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 | 32 ++++++++++++++++++++++++++++ arch/x86/mm/fault.c | 9 ++++++++ 2 files changed, 41 insertions(+) diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 317fc59b512c..c04e68ef47da 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -237,6 +237,38 @@ 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) +{ + asm_volatile_goto("1: wrussd %1, (%0)\n" + _ASM_EXTABLE(1b, %l[fail]) + :: "r" (addr), "r" (val) + :: fail); + return 0; +fail: + return -1; +} +#else +static inline int write_user_shstk_32(unsigned long addr, unsigned int val) +{ + WARN_ONCE(1, "write_user_shstk_32 used but not supported.\n"); + return -EFAULT; +} +#endif + +static inline int write_user_shstk_64(unsigned long addr, unsigned long val) +{ + asm_volatile_goto("1: wrussq %1, (%0)\n" + _ASM_EXTABLE(1b, %l[fail]) + :: "r" (addr), "r" (val) + :: fail); + return 0; +fail: + return -1; +} +#endif /* CONFIG_X86_INTEL_CET */ + #define nop() asm volatile ("nop") diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 7c3877a982f4..4d4ac57a4ba2 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1305,6 +1305,15 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, error_code |= X86_PF_USER; flags |= FAULT_FLAG_USER; } else { + /* + * WRUSS is a kernel instrcution and but writes + * to user shadow stack. When a fault occurs, + * both X86_PF_USER and X86_PF_SHSTK are set. + * Clear X86_PF_USER here. + */ + if ((error_code & (X86_PF_USER | X86_PF_SHSTK)) == + (X86_PF_USER | X86_PF_SHSTK)) + error_code &= ~X86_PF_USER; if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } -- 2.17.1