mm: Introduce VM_SHADOW_STACK for shadow stack memory
authorYu-cheng Yu <yu-cheng.yu@intel.com>
Tue, 13 Jun 2023 00:10:40 +0000 (17:10 -0700)
committerRick Edgecombe <rick.p.edgecombe@intel.com>
Tue, 11 Jul 2023 21:12:19 +0000 (14:12 -0700)
New hardware extensions implement support for shadow stack memory, such
as x86 Control-flow Enforcement Technology (CET). Add a new VM flag to
identify these areas, for example, to be used to properly indicate shadow
stack PTEs to the hardware.

Shadow stack VMA creation will be tightly controlled and limited to
anonymous memory to make the implementation simpler and since that is all
that is required. The solution will rely on pte_mkwrite() to create the
shadow stack PTEs, so it will not be required for vm_get_page_prot() to
learn how to create shadow stack memory. For this reason document that
VM_SHADOW_STACK should not be mixed with VM_SHARED.

Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Acked-by: Mike Rapoport (IBM) <rppt@kernel.org>
Acked-by: David Hildenbrand <david@redhat.com>
Tested-by: Mark Brown <broonie@kernel.org>
Tested-by: Pengfei Xu <pengfei.xu@intel.com>
Tested-by: John Allen <john.allen@amd.com>
Tested-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/all/20230613001108.3040476-15-rick.p.edgecombe%40intel.com
Documentation/filesystems/proc.rst
fs/proc/task_mmu.c
include/linux/mm.h

index 7897a7dafcbc18caac24bbe9345162f611d111ce..6ccb57089a0631fcfb205e1cbd2d978008e43b23 100644 (file)
@@ -566,6 +566,7 @@ encoded manner. The codes are the following:
     mt    arm64 MTE allocation tags are enabled
     um    userfaultfd missing tracking
     uw    userfaultfd wr-protect tracking
+    ss    shadow stack page
     ==    =======================================
 
 Note that there is no guarantee that every flag and associated mnemonic will
index 507cd4e59d074d2b65cac1adeaad4257fb5e39bc..cfab855fe7e96282000ba0b82a3e2fd9a7fda267 100644 (file)
@@ -709,6 +709,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
                [ilog2(VM_UFFD_MINOR)]  = "ui",
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
+#ifdef CONFIG_X86_USER_SHADOW_STACK
+               [ilog2(VM_SHADOW_STACK)] = "ss",
+#endif
        };
        size_t i;
 
index 82990f3390f6c07768f062ef7bdd5c5394d84b48..f6c2ebde62b37f4bf9c3a43b68b63077f1e0a018 100644 (file)
@@ -319,11 +319,13 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_HIGH_ARCH_BIT_2     34      /* bit only usable on 64-bit architectures */
 #define VM_HIGH_ARCH_BIT_3     35      /* bit only usable on 64-bit architectures */
 #define VM_HIGH_ARCH_BIT_4     36      /* bit only usable on 64-bit architectures */
+#define VM_HIGH_ARCH_BIT_5     37      /* bit only usable on 64-bit architectures */
 #define VM_HIGH_ARCH_0 BIT(VM_HIGH_ARCH_BIT_0)
 #define VM_HIGH_ARCH_1 BIT(VM_HIGH_ARCH_BIT_1)
 #define VM_HIGH_ARCH_2 BIT(VM_HIGH_ARCH_BIT_2)
 #define VM_HIGH_ARCH_3 BIT(VM_HIGH_ARCH_BIT_3)
 #define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4)
+#define VM_HIGH_ARCH_5 BIT(VM_HIGH_ARCH_BIT_5)
 #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */
 
 #ifdef CONFIG_ARCH_HAS_PKEYS
@@ -339,6 +341,12 @@ extern unsigned int kobjsize(const void *objp);
 #endif
 #endif /* CONFIG_ARCH_HAS_PKEYS */
 
+#ifdef CONFIG_X86_USER_SHADOW_STACK
+# define VM_SHADOW_STACK       VM_HIGH_ARCH_5 /* Should not be set with VM_SHARED */
+#else
+# define VM_SHADOW_STACK       VM_NONE
+#endif
+
 #if defined(CONFIG_X86)
 # define VM_PAT                VM_ARCH_1       /* PAT reserves whole VMA at once (x86) */
 #elif defined(CONFIG_PPC)