OSDN Git Service

Merge tag 'x86_shstk_for_6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[tomoyo/tomoyo-test1.git] / arch / x86 / mm / fault.c
index 2e861b9..ab778ea 100644 (file)
@@ -1112,8 +1112,22 @@ access_error(unsigned long error_code, struct vm_area_struct *vma)
                                       (error_code & X86_PF_INSTR), foreign))
                return 1;
 
+       /*
+        * Shadow stack accesses (PF_SHSTK=1) are only permitted to
+        * shadow stack VMAs. All other accesses result in an error.
+        */
+       if (error_code & X86_PF_SHSTK) {
+               if (unlikely(!(vma->vm_flags & VM_SHADOW_STACK)))
+                       return 1;
+               if (unlikely(!(vma->vm_flags & VM_WRITE)))
+                       return 1;
+               return 0;
+       }
+
        if (error_code & X86_PF_WRITE) {
                /* write, present and write, not present: */
+               if (unlikely(vma->vm_flags & VM_SHADOW_STACK))
+                       return 1;
                if (unlikely(!(vma->vm_flags & VM_WRITE)))
                        return 1;
                return 0;
@@ -1305,6 +1319,14 @@ void do_user_addr_fault(struct pt_regs *regs,
 
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
+       /*
+        * Read-only permissions can not be expressed in shadow stack PTEs.
+        * Treat all shadow stack accesses as WRITE faults. This ensures
+        * that the MM will prepare everything (e.g., break COW) such that
+        * maybe_mkwrite() can create a proper shadow stack PTE.
+        */
+       if (error_code & X86_PF_SHSTK)
+               flags |= FAULT_FLAG_WRITE;
        if (error_code & X86_PF_WRITE)
                flags |= FAULT_FLAG_WRITE;
        if (error_code & X86_PF_INSTR)