Message ID | 20230218211433.26859-21-rick.p.edgecombe@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp555423wrn; Sat, 18 Feb 2023 13:21:06 -0800 (PST) X-Google-Smtp-Source: AK7set+FUl0ESnaitYI85k2YBzHBYgj+AZxwZyGd+P/OS++CSHLc2GPAXyBOrFHeYjzo6AhcKOjs X-Received: by 2002:aa7:97a3:0:b0:5a9:c535:dba3 with SMTP id d3-20020aa797a3000000b005a9c535dba3mr7468950pfq.25.1676755266579; Sat, 18 Feb 2023 13:21:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676755266; cv=none; d=google.com; s=arc-20160816; b=fC9zDvpA2onSCprUuAyQo1k6UQTjPoD8vwcX2UUf+xgWGwxYSizZwADgGd0YOt/J1F ArwMZSCtEI1+TwITzc/hgre13sRcOoEvDQO9dwn73tXlckI2mzsOwNSnB0oVYhyZ67gd JTlUEuCuRNqr8BHfLZDwnwOAlJSS8cx7d6qTRxT9NMeU4VmnWrRFpW+hDwZW8z+XqGsG SXSsTMWuO3qRk9ioa4aE1XkI6di3lDFixQOdiBFA0Xq+NLbcEwJxIP3VVYcNigbMG/7O Dm+6Fhz6CXfL+XDG/S9Bm/RegKYyCMoR9SXKnXUln4rOtUUiGxbHgJC/K8gNASOYPAt1 P7+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=9UaPp7NFG0LEcPHMvr1nfm8BlHPzTXSOfJPjX78pISI=; b=afJcsPmy6kB6uIlBvSvI9AF4zfjQJ1fmKxRcKfm9Ev6MAhvVx8KB3SF+2nPSkiDYPI OWvT1zIAuK13vNdXkH5p4aNKtFx70jLQysF5Bz7G1tqE5UFnImVvf6IuGy5KzX2A57pO XH3Dw4y917OGCm1l7M8W7u2/BllM68qE8QYLibWM4BIGK4Kr69j+ceOCV18gT+0zQil0 reKxzaRSCcqdjYaJ8ZCmuoiUGm5b8obQ9560gXkjDR7PqpugkjTwCI54fKaiEYFspz5T zpm3aG1/zcng0lgI5zukSYlEYTYz4aqZqSxnt1g/wm4MzIo6QoOdoQ05ASYIOw9TyOu8 ADAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=LxLWhvIU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o16-20020a056a0015d000b005a9dd8ef30csi8059778pfu.216.2023.02.18.13.20.52; Sat, 18 Feb 2023 13:21:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=LxLWhvIU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230146AbjBRVUb (ORCPT <rfc822;assdfgzxcv4@gmail.com> + 99 others); Sat, 18 Feb 2023 16:20:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42762 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229836AbjBRVTv (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 18 Feb 2023 16:19:51 -0500 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F72C17177; Sat, 18 Feb 2023 13:17:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676755057; x=1708291057; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=FRX2Zip/lmlZmsFz5KdG4yfHn5/JjBj845luOn8deCo=; b=LxLWhvIUq99wc9yIlNXxwllW1u1pqMUk9nyDEJHTrOTv2txHj6A/2asV dySGPJ+mRt8PmXNVyPGCLqscMxEUVFEESat5UMmZZUGuLg/Y809yveOAC gbaZEtxYj1Dsev6w+Kp8ZRKVntzD9fpk0q/IkpaqoiLX2w2jr0EmqCXMV 0myzWOfcbYM10+Kd7F3dRopiEgkqp+9DGqPqwvGVV+JD/3dw3ULLyAdhC FYrbhy1PAH0hgznC3COSQ+YawWYhq2KVvX9hQW+ttwQThC9JXZqgABl9M IT1bpuV8f1zshNVoQ8HSSRvDel7RYJvI4aopmfP3IPlMrFyOiVHVWhD+T Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10625"; a="418427526" X-IronPort-AV: E=Sophos;i="5.97,309,1669104000"; d="scan'208";a="418427526" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2023 13:16:13 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10625"; a="664241668" X-IronPort-AV: E=Sophos;i="5.97,309,1669104000"; d="scan'208";a="664241668" Received: from adityava-mobl1.amr.corp.intel.com (HELO rpedgeco-desk.amr.corp.intel.com) ([10.209.80.223]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2023 13:16:12 -0800 From: Rick Edgecombe <rick.p.edgecombe@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>, Weijiang Yang <weijiang.yang@intel.com>, "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>, John Allen <john.allen@amd.com>, kcc@google.com, eranian@google.com, rppt@kernel.org, jamorris@linux.microsoft.com, dethoma@microsoft.com, akpm@linux-foundation.org, Andrew.Cooper3@citrix.com, christina.schimpe@intel.com, david@redhat.com, debug@rivosinc.com Cc: rick.p.edgecombe@intel.com Subject: [PATCH v6 20/41] x86/mm: Teach pte_mkwrite() about stack memory Date: Sat, 18 Feb 2023 13:14:12 -0800 Message-Id: <20230218211433.26859-21-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230218211433.26859-1-rick.p.edgecombe@intel.com> References: <20230218211433.26859-1-rick.p.edgecombe@intel.com> X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758205330329604396?= X-GMAIL-MSGID: =?utf-8?q?1758205330329604396?= |
Series |
Shadow stacks for userspace
|
|
Commit Message
Edgecombe, Rick P
Feb. 18, 2023, 9:14 p.m. UTC
If a VMA has the VM_SHADOW_STACK flag, it is shadow stack memory. So when it is made writable with pte_mkwrite(), it should create shadow stack memory, not conventionally writable memory. Now that pte_mkwrite() takes a VMA, and places where shadow stack memory might be created pass one, pte_mkwrite() can know when it should do this. So make pte_mkwrite() create shadow stack memory when the VMA has the VM_SHADOW_STACK flag. Do the same thing for pmd_mkwrite(). This requires referencing VM_SHADOW_STACK in these functions, which are currently defined in pgtable.h, however mm.h (where VM_SHADOW_STACK is located) can't be pulled in without causing problems for files that reference pgtable.h. So also move pte/pmd_mkwrite() into pgtable.c, where they can safely reference VM_SHADOW_STACK. Tested-by: Pengfei Xu <pengfei.xu@intel.com> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> --- v6: - New patch --- arch/x86/include/asm/pgtable.h | 20 ++------------------ arch/x86/mm/pgtable.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 18 deletions(-)
Comments
On Sat, Feb 18, 2023 at 01:14:12PM -0800, Rick Edgecombe wrote: > If a VMA has the VM_SHADOW_STACK flag, it is shadow stack memory. So > when it is made writable with pte_mkwrite(), it should create shadow > stack memory, not conventionally writable memory. Now that pte_mkwrite() > takes a VMA, and places where shadow stack memory might be created pass > one, pte_mkwrite() can know when it should do this. > > So make pte_mkwrite() create shadow stack memory when the VMA has the > VM_SHADOW_STACK flag. Do the same thing for pmd_mkwrite(). > > This requires referencing VM_SHADOW_STACK in these functions, which are > currently defined in pgtable.h, however mm.h (where VM_SHADOW_STACK is > located) can't be pulled in without causing problems for files that > reference pgtable.h. So also move pte/pmd_mkwrite() into pgtable.c, where > they can safely reference VM_SHADOW_STACK. > > Tested-by: Pengfei Xu <pengfei.xu@intel.com> > Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Is there any realistic performance impact from making these not inline now? Reviewed-by: Kees Cook <keescook@chromium.org>
On Sun, 2023-02-19 at 12:41 -0800, Kees Cook wrote: > On Sat, Feb 18, 2023 at 01:14:12PM -0800, Rick Edgecombe wrote: > > If a VMA has the VM_SHADOW_STACK flag, it is shadow stack memory. > > So > > when it is made writable with pte_mkwrite(), it should create > > shadow > > stack memory, not conventionally writable memory. Now that > > pte_mkwrite() > > takes a VMA, and places where shadow stack memory might be created > > pass > > one, pte_mkwrite() can know when it should do this. > > > > So make pte_mkwrite() create shadow stack memory when the VMA has > > the > > VM_SHADOW_STACK flag. Do the same thing for pmd_mkwrite(). > > > > This requires referencing VM_SHADOW_STACK in these functions, which > > are > > currently defined in pgtable.h, however mm.h (where VM_SHADOW_STACK > > is > > located) can't be pulled in without causing problems for files that > > reference pgtable.h. So also move pte/pmd_mkwrite() into pgtable.c, > > where > > they can safely reference VM_SHADOW_STACK. > > > > Tested-by: Pengfei Xu <pengfei.xu@intel.com> > > Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> > > Is there any realistic performance impact from making these not > inline > now? Hmm, I can't say definitively. I would think in write protecting operations, the big cost would not be the PTE setters. For mapping things read-only from the beginning (user text, etc), I'm not sure. I guess it gives the compiler less flexibility, but also gives it the option to have one copy and so less text size overall for the kernel. Are there any specific microbenchmarks we could run?
On Sat, Feb 18, 2023 at 01:14:12PM -0800, Rick Edgecombe wrote: >If a VMA has the VM_SHADOW_STACK flag, it is shadow stack memory. So >when it is made writable with pte_mkwrite(), it should create shadow >stack memory, not conventionally writable memory. Now that pte_mkwrite() >takes a VMA, and places where shadow stack memory might be created pass >one, pte_mkwrite() can know when it should do this. > >So make pte_mkwrite() create shadow stack memory when the VMA has the >VM_SHADOW_STACK flag. Do the same thing for pmd_mkwrite(). > >This requires referencing VM_SHADOW_STACK in these functions, which are >currently defined in pgtable.h, however mm.h (where VM_SHADOW_STACK is >located) can't be pulled in without causing problems for files that >reference pgtable.h. So also move pte/pmd_mkwrite() into pgtable.c, where >they can safely reference VM_SHADOW_STACK. > >Tested-by: Pengfei Xu <pengfei.xu@intel.com> >Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> > Acked-by: Deepak Gupta <debug@rivosinc.com>
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 292a3b75d7fa..6b7106457bfb 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -456,15 +456,7 @@ static inline pte_t pte_mkwrite_kernel(pte_t pte) struct vm_area_struct; -static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) -{ - pte = pte_mkwrite_kernel(pte); - - if (pte_dirty(pte)) - pte = pte_clear_saveddirty(pte); - - return pte; -} +pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma); static inline pte_t pte_mkhuge(pte_t pte) { @@ -601,15 +593,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) return pmd_set_flags(pmd, _PAGE_ACCESSED); } -static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) -{ - pmd = pmd_set_flags(pmd, _PAGE_RW); - - if (pmd_dirty(pmd)) - pmd = pmd_clear_saveddirty(pmd); - - return pmd; -} +pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma); static inline pud_t pud_set_flags(pud_t pud, pudval_t set) { diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index e4f499eb0f29..98856bcc8102 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -880,3 +880,29 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) #endif /* CONFIG_X86_64 */ #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ + +pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_SHADOW_STACK) + return pte_mkwrite_shstk(pte); + + pte = pte_mkwrite_kernel(pte); + + if (pte_dirty(pte)) + pte = pte_clear_saveddirty(pte); + + return pte; +} + +pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_SHADOW_STACK) + return pmd_mkwrite_shstk(pmd); + + pmd = pmd_set_flags(pmd, _PAGE_RW); + + if (pmd_dirty(pmd)) + pmd = pmd_clear_saveddirty(pmd); + + return pmd; +}