Shadow stack accesses are writes from handle_mm_fault() perspective. So to generate the correct PTE, maybe_mkwrite() will rely on the presence of VM_SHADOW_STACK or VM_WRITE in the vma. In future patches, when VM_SHADOW_STACK is actually creatable by userspace, a problem could happen if a user calls mprotect( , , PROT_WRITE) on VM_SHADOW_STACK shadow stack memory. The code would then be confused in the event of shadow stack accesses, and create a writable PTE for a shadow stack access. Then the process would fault in a loop. Prevent this from happening by blocking this kind of memory (VM_WRITE and VM_SHADOW_STACK) from being created, instead of complicating the fault handler logic to handle it. Add an x86 arch_validate_flags() implementation to handle the check. Rename the uapi/asm/mman.h header guard to be able to use it for arch/x86/include/asm/mman.h where the arch_validate_flags() will be. Signed-off-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> --- v1: - New patch. arch/x86/include/asm/mman.h | 21 +++++++++++++++++++++ arch/x86/include/uapi/asm/mman.h | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 arch/x86/include/asm/mman.h diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h new file mode 100644 index 000000000000..b44fe31deb3a --- /dev/null +++ b/arch/x86/include/asm/mman.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_MMAN_H +#define _ASM_X86_MMAN_H + +#include <linux/mm.h> +#include <uapi/asm/mman.h> + +#ifdef CONFIG_X86_SHADOW_STACK +static inline bool arch_validate_flags(unsigned long vm_flags) +{ + if ((vm_flags & VM_SHADOW_STACK) && (vm_flags & VM_WRITE)) + return false; + + return true; +} + +#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) + +#endif /* CONFIG_X86_SHADOW_STACK */ + +#endif /* _ASM_X86_MMAN_H */ diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h index d4a8d0424bfb..9704e27c4d24 100644 --- a/arch/x86/include/uapi/asm/mman.h +++ b/arch/x86/include/uapi/asm/mman.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _ASM_X86_MMAN_H -#define _ASM_X86_MMAN_H +#ifndef _UAPI_ASM_X86_MMAN_H +#define _UAPI_ASM_X86_MMAN_H #define MAP_32BIT 0x40 /* only give out 32bit addresses */ @@ -28,4 +28,4 @@ #include <asm-generic/mman.h> -#endif /* _ASM_X86_MMAN_H */ +#endif /* _UAPI_ASM_X86_MMAN_H */ -- 2.17.1