From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A020C433DB for ; Wed, 10 Feb 2021 21:38:19 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id D634764EDC for ; Wed, 10 Feb 2021 21:38:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D634764EDC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 4D40D6B0005; Wed, 10 Feb 2021 16:38:18 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 485D96B0006; Wed, 10 Feb 2021 16:38:18 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 34CED6B006C; Wed, 10 Feb 2021 16:38:18 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0135.hostedemail.com [216.40.44.135]) by kanga.kvack.org (Postfix) with ESMTP id 188396B0005 for ; Wed, 10 Feb 2021 16:38:18 -0500 (EST) Received: from smtpin25.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id DBCF48016D0F for ; Wed, 10 Feb 2021 21:38:17 +0000 (UTC) X-FDA: 77803671834.25.news22_2e036da27613 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin25.hostedemail.com (Postfix) with ESMTP id B5D321803F79A for ; Wed, 10 Feb 2021 21:38:17 +0000 (UTC) X-HE-Tag: news22_2e036da27613 X-Filterd-Recvd-Size: 7265 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by imf46.hostedemail.com (Postfix) with ESMTP for ; Wed, 10 Feb 2021 21:38:15 +0000 (UTC) IronPort-SDR: ZtcHLHHm54f72YCnJcT+J8xmLKAVWCVQI7KF1aLViu9vUpiNzq9XGM/74ci/DGzWhHC1ZxEYzZ TTlwSR0lca9A== X-IronPort-AV: E=McAfee;i="6000,8403,9891"; a="266997245" X-IronPort-AV: E=Sophos;i="5.81,169,1610438400"; d="scan'208";a="266997245" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Feb 2021 13:38:14 -0800 IronPort-SDR: lfBvtJxzP7eM7rxhNTEkSJQFKW6pSPQwDWDjL0xrSvc0rO529nfDOd01DxdtVXlVhrVpvVqI9D WUnuOVuiu4FQ== X-IronPort-AV: E=Sophos;i="5.81,169,1610438400"; d="scan'208";a="375624618" Received: from yyu32-mobl1.amr.corp.intel.com (HELO [10.212.188.167]) ([10.212.188.167]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Feb 2021 13:38:12 -0800 Subject: Re: [PATCH v20 21/25] x86/cet/shstk: Handle signals for shadow stack To: Kees Cook Cc: 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 , Borislav Petkov , Cyrill Gorcunov , Dave Hansen , Eugene Syromiatnikov , Florian Weimer , "H.J. Lu" , Jann Horn , Jonathan Corbet , Mike Kravetz , Nadav Amit , Oleg Nesterov , Pavel Machek , Peter Zijlstra , Randy Dunlap , "Ravi V. Shankar" , Vedvyas Shanbhogue , Dave Martin , Weijiang Yang , Pengfei Xu , haitao.huang@intel.com References: <20210210175703.12492-1-yu-cheng.yu@intel.com> <20210210175703.12492-22-yu-cheng.yu@intel.com> <202102101154.CEF2606E@keescook> From: "Yu, Yu-cheng" Message-ID: <57dcc827-052a-94cd-31d4-286675f9d506@intel.com> Date: Wed, 10 Feb 2021 13:38:10 -0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <202102101154.CEF2606E@keescook> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On 2/10/2021 11:58 AM, Kees Cook wrote: > On Wed, Feb 10, 2021 at 09:56:59AM -0800, Yu-cheng Yu wrote: >> To deliver a signal, create a shadow stack restore token and put the token >> and the signal restorer address on the shadow stack. For sigreturn, verify >> the token and restore from it the shadow stack pointer. >> >> A shadow stack restore token marks a restore point of the shadow stack. >> The token is distinctively different from any shadow stack address. > > How is it different? It seems like it just has the last 2 bits > masked/set? > For example, for 64-bit apps, A shadow stack pointer value (*ssp) has to be in some code area, but for a token, (*ptr_of_token) = (ptr_of_token + 8), which has to be within the same shadow stack area. In cet_verify_rstor_token(), this is checked. >> In sigreturn, restoring from a token ensures the target address is the >> location pointed by the token. > > As in, a token (real stack address with 2-bit mask) is checked against > the real stack address? I don't see a comparison -- it only checks that > it is < TASK_SIZE. > > How does cet_restore_signal() figure into this? (As in, the MSR writes?) > The kernel takes the restore address from the token. It will not mistakenly take a wrong address from the shadow stack. I will put this in my commit logs. [...] >> Introduce WRUSS, which is a kernel-mode instruction but writes directly to >> user shadow stack. It is used to construct the user signal stack as >> described above. >> >> Currently there is no systematic facility for extending a signal context. >> Introduce a signal context extension 'struct sc_ext', which is used to save >> shadow stack restore token address and WAIT_ENDBR status. WAIT_ENDBR will >> be introduced later in the Indirect Branch Tracking (IBT) series, but add >> that into sc_ext now to keep the struct stable in case the IBT series is >> applied later. >> >> Signed-off-by: Yu-cheng Yu [...] >> diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c >> index d25a03215984..08e43d9b5176 100644 >> --- a/arch/x86/kernel/cet.c >> +++ b/arch/x86/kernel/cet.c >> @@ -19,6 +19,8 @@ >> #include >> #include >> #include >> +#include >> +#include >> >> static void start_update_msrs(void) >> { >> @@ -72,6 +74,80 @@ static unsigned long alloc_shstk(unsigned long size, int flags) >> return addr; >> } >> >> +#define TOKEN_MODE_MASK 3UL >> +#define TOKEN_MODE_64 1UL >> +#define IS_TOKEN_64(token) (((token) & TOKEN_MODE_MASK) == TOKEN_MODE_64) >> +#define IS_TOKEN_32(token) (((token) & TOKEN_MODE_MASK) == 0) >> + >> +/* >> + * Verify the restore token at the address of 'ssp' is >> + * valid and then set shadow stack pointer according to the >> + * token. >> + */ >> +int cet_verify_rstor_token(bool ia32, unsigned long ssp, >> + unsigned long *new_ssp) >> +{ >> + unsigned long token; >> + >> + *new_ssp = 0; >> + >> + if (!IS_ALIGNED(ssp, 8)) >> + return -EINVAL; >> + >> + if (get_user(token, (unsigned long __user *)ssp)) >> + return -EFAULT; >> + >> + /* Is 64-bit mode flag correct? */ >> + if (!ia32 && !IS_TOKEN_64(token)) >> + return -EINVAL; >> + else if (ia32 && !IS_TOKEN_32(token)) >> + return -EINVAL; >> + >> + token &= ~TOKEN_MODE_MASK; >> + >> + /* >> + * Restore address properly aligned? >> + */ >> + if ((!ia32 && !IS_ALIGNED(token, 8)) || !IS_ALIGNED(token, 4)) >> + return -EINVAL; >> + >> + /* >> + * Token was placed properly? >> + */ >> + if (((ALIGN_DOWN(token, 8) - 8) != ssp) || token >= TASK_SIZE_MAX) >> + return -EINVAL; >> + >> + *new_ssp = token; >> + return 0; >> +} >> + >> +/* >> + * Create a restore token on the shadow stack. >> + * A token is always 8-byte and aligned to 8. >> + */ >> +static int create_rstor_token(bool ia32, unsigned long ssp, >> + unsigned long *new_ssp) >> +{ >> + unsigned long addr; >> + >> + *new_ssp = 0; >> + >> + if ((!ia32 && !IS_ALIGNED(ssp, 8)) || !IS_ALIGNED(ssp, 4)) >> + return -EINVAL; >> + >> + addr = ALIGN_DOWN(ssp, 8) - 8; >> + >> + /* Is the token for 64-bit? */ >> + if (!ia32) >> + ssp |= TOKEN_MODE_64; >> + >> + if (write_user_shstk_64(addr, ssp)) >> + return -EFAULT; >> + >> + *new_ssp = addr; >> + return 0; >> +} >> + [...]