From: Sean Christopherson <sean.j.christopher...@intel.com>

Add vm_ops()->may_mprotect() to check additional constraints.

SGX uses this callback to add two constraints:

1. Verify that the address range does not have holes: for each page
   address, there is an actual enclave page created.
2. Mapped permissions do not surpass the lowest enclave page permissions
   in the address range.

linux...@kvack.org
Andrew Morton <a...@linux-foundation.org>
Acked-by: Jethro Beekman <jet...@fortanix.com>
Signed-off-by: Sean Christopherson <sean.j.christopher...@intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>
---
 include/linux/mm.h |  2 ++
 mm/mprotect.c      | 14 +++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5a323422d783..dbcc2846b3b8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -546,6 +546,8 @@ struct vm_operations_struct {
        void (*close)(struct vm_area_struct * area);
        int (*split)(struct vm_area_struct * area, unsigned long addr);
        int (*mremap)(struct vm_area_struct * area);
+       int (*may_mprotect)(struct vm_area_struct *vma, unsigned long start,
+                           unsigned long end, unsigned long prot);
        vm_fault_t (*fault)(struct vm_fault *vmf);
        vm_fault_t (*huge_fault)(struct vm_fault *vmf,
                        enum page_entry_size pe_size);
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 494192ca954b..079ba92df377 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -603,13 +603,21 @@ static int do_mprotect_pkey(unsigned long start, size_t 
len,
                        goto out;
                }
 
+               tmp = vma->vm_end;
+               if (tmp > end)
+                       tmp = end;
+
+               if (vma->vm_ops && vma->vm_ops->may_mprotect) {
+                       error = vma->vm_ops->may_mprotect(vma, nstart, tmp,
+                                                         prot);
+                       if (error)
+                               goto out;
+               }
+
                error = security_file_mprotect(vma, reqprot, prot);
                if (error)
                        goto out;
 
-               tmp = vma->vm_end;
-               if (tmp > end)
-                       tmp = end;
                error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
                if (error)
                        goto out;
-- 
2.25.1

Reply via email to