summarylogtreecommitdiffstats
path: root/0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch
diff options
context:
space:
mode:
authorJarkko Sakkinen2022-04-05 07:55:53 +0300
committerJarkko Sakkinen2022-04-05 08:12:22 +0300
commit9e595612af76514fe6b9fecdc384a33473c7fe08 (patch)
tree2d2716e70c266aa4e0c4ba619318d69d258955c1 /0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch
parent71077f1ec07d0cdb3bf641af1263865b04eaafa3 (diff)
downloadaur-9e595612af76514fe6b9fecdc384a33473c7fe08.tar.gz
bump sgx2 series v3
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@iki.fi>
Diffstat (limited to '0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch')
-rw-r--r--0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch223
1 files changed, 0 insertions, 223 deletions
diff --git a/0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch b/0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch
deleted file mode 100644
index defee425b1d2..000000000000
--- a/0006-x86-sgx-Support-VMA-permissions-more-relaxed-than-en.patch
+++ /dev/null
@@ -1,223 +0,0 @@
-From 721f971c8c55d4b3eff23466c48235f121e038fe Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:28 -0800
-Subject: [PATCH 06/34] x86/sgx: Support VMA permissions more relaxed than
- enclave permissions
-
-=== Summary ===
-
-An SGX VMA can only be created if its permissions are the same or
-weaker than the Enclave Page Cache Map (EPCM) permissions. After VMA
-creation this same rule is again enforced by the page fault handler:
-faulted enclave pages are required to have equal or more relaxed
-EPCM permissions than the VMA permissions.
-
-On SGX1 systems the additional enforcement in the page fault handler
-is redundant and on SGX2 systems it incorrectly prevents access.
-On SGX1 systems it is unnecessary to repeat the enforcement of the
-permission rule. The rule used during original VMA creation will
-ensure that any access attempt will use correct permissions.
-With SGX2 the EPCM permissions of a page can change after VMA
-creation resulting in the VMA permissions potentially being more
-relaxed than the EPCM permissions and the page fault handler
-incorrectly blocking valid access attempts.
-
-Enable the VMA's pages to remain accessible while ensuring that
-the PTEs are installed to match the EPCM permissions but not be
-more relaxed than the VMA permissions.
-
-=== Full Changelog ===
-
-An SGX enclave is an area of memory where parts of an application
-can reside. First an enclave is created and loaded (from
-non-enclave memory) with the code and data of an application,
-then user space can map (mmap()) the enclave memory to
-be able to enter the enclave at its defined entry points for
-execution within it.
-
-The hardware maintains a secure structure, the Enclave Page Cache Map
-(EPCM), that tracks the contents of the enclave. Of interest here is
-its tracking of the enclave page permissions. When a page is loaded
-into the enclave its permissions are specified and recorded in the
-EPCM. In parallel the kernel maintains permissions within the
-page table entries (PTEs) and the rule is that PTE permissions
-are not allowed to be more relaxed than the EPCM permissions.
-
-A new mapping (mmap()) of enclave memory can only succeed if the
-mapping has the same or weaker permissions than the permissions that
-were vetted during enclave creation. This is enforced by
-sgx_encl_may_map() that is called on the mmap() as well as mprotect()
-paths. This rule remains.
-
-One feature of SGX2 is to support the modification of EPCM permissions
-after enclave initialization. Enclave pages may thus already be part
-of a VMA at the time their EPCM permissions are changed resulting
-in the VMA's permissions potentially being more relaxed than the EPCM
-permissions.
-
-Allow permissions of existing VMAs to be more relaxed than EPCM
-permissions in preparation for dynamic EPCM permission changes
-made possible in SGX2. New VMAs that attempt to have more relaxed
-permissions than EPCM permissions continue to be unsupported.
-
-Reasons why permissions of existing VMAs are allowed to be more relaxed
-than EPCM permissions instead of dynamically changing VMA permissions
-when EPCM permissions change are:
-1) Changing VMA permissions involve splitting VMAs which is an
- operation that can fail. Additionally changing EPCM permissions of
- a range of pages could also fail on any of the pages involved.
- Handling these error cases causes problems. For example, if an
- EPCM permission change fails and the VMA has already been split
- then it is not possible to undo the VMA split nor possible to
- undo the EPCM permission changes that did succeed before the
- failure.
-2) The kernel has little insight into the user space where EPCM
- permissions are controlled from. For example, a RW page may
- be made RO just before it is made RX and splitting the VMAs
- while the VMAs may change soon is unnecessary.
-
-Remove the extra permission check called on a page fault
-(vm_operations_struct->fault) or during debugging
-(vm_operations_struct->access) when loading the enclave page from swap
-that ensures that the VMA permissions are not more relaxed than the
-EPCM permissions. Since a VMA could only exist if it passed the
-original permission checks during mmap() and a VMA may indeed
-have more relaxed permissions than the EPCM permissions this extra
-permission check is no longer appropriate.
-
-With the permission check removed, ensure that PTEs do
-not blindly inherit the VMA permissions but instead the permissions
-that the VMA and EPCM agree on. PTEs for writable pages (from VMA
-and enclave perspective) are installed with the writable bit set,
-reducing the need for this additional flow to the permission mismatch
-cases handled next.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- Documentation/x86/sgx.rst | 10 +++++++++
- arch/x86/kernel/cpu/sgx/encl.c | 38 ++++++++++++++++++----------------
- 2 files changed, 30 insertions(+), 18 deletions(-)
-
-diff --git a/Documentation/x86/sgx.rst b/Documentation/x86/sgx.rst
-index 89ff924b1480..5659932728a5 100644
---- a/Documentation/x86/sgx.rst
-+++ b/Documentation/x86/sgx.rst
-@@ -99,6 +99,16 @@ The relationships between the different permission masks are:
- * PTEs are installed to match the EPCM permissions, but not be more
- relaxed than the VMA permissions.
-
-+On systems supporting SGX2 EPCM permissions may change while the
-+enclave page belongs to a VMA without impacting the VMA permissions.
-+This means that a running VMA may appear to allow access to an enclave
-+page that is not allowed by its EPCM permissions. For example, when an
-+enclave page with RW EPCM permissions is mapped by a RW VMA but is
-+subsequently changed to have read-only EPCM permissions. The kernel
-+continues to maintain correct access to the enclave page through the
-+PTE that will ensure that only access allowed by both the VMA
-+and EPCM permissions are permitted.
-+
- Application interface
- =====================
-
-diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 6fa3d0a14b93..2f80f9e5e8c6 100644
---- a/arch/x86/kernel/cpu/sgx/encl.c
-+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -132,10 +132,8 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page,
- }
-
- static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
-- unsigned long addr,
-- unsigned long vm_flags)
-+ unsigned long addr)
- {
-- unsigned long vm_prot_bits = vm_flags & (VM_READ | VM_WRITE | VM_EXEC);
- struct sgx_epc_page *epc_page;
- struct sgx_encl_page *entry;
-
-@@ -143,14 +141,6 @@ static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
- if (!entry)
- return ERR_PTR(-EFAULT);
-
-- /*
-- * Verify that the faulted page has equal or higher build time
-- * permissions than the VMA permissions (i.e. the subset of {VM_READ,
-- * VM_WRITE, VM_EXECUTE} in vma->vm_flags).
-- */
-- if ((entry->vm_max_prot_bits & vm_prot_bits) != vm_prot_bits)
-- return ERR_PTR(-EFAULT);
--
- /* Entry successfully located. */
- if (entry->epc_page) {
- if (entry->desc & SGX_ENCL_PAGE_BEING_RECLAIMED)
-@@ -179,7 +169,9 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
- {
- unsigned long addr = (unsigned long)vmf->address;
- struct vm_area_struct *vma = vmf->vma;
-+ unsigned long page_prot_bits;
- struct sgx_encl_page *entry;
-+ unsigned long vm_prot_bits;
- unsigned long phys_addr;
- struct sgx_encl *encl;
- vm_fault_t ret;
-@@ -196,7 +188,7 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
-
- mutex_lock(&encl->lock);
-
-- entry = sgx_encl_load_page(encl, addr, vma->vm_flags);
-+ entry = sgx_encl_load_page(encl, addr);
- if (IS_ERR(entry)) {
- mutex_unlock(&encl->lock);
-
-@@ -208,7 +200,19 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
-
- phys_addr = sgx_get_epc_phys_addr(entry->epc_page);
-
-- ret = vmf_insert_pfn(vma, addr, PFN_DOWN(phys_addr));
-+ /*
-+ * Insert PTE to match the EPCM page permissions ensured to not
-+ * exceed the VMA permissions.
-+ */
-+ vm_prot_bits = vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC);
-+ page_prot_bits = entry->vm_max_prot_bits & vm_prot_bits;
-+ /*
-+ * Add VM_SHARED so that PTE is made writable right away if VMA
-+ * and EPCM are writable (no COW in SGX).
-+ */
-+ page_prot_bits |= (vma->vm_flags & VM_SHARED);
-+ ret = vmf_insert_pfn_prot(vma, addr, PFN_DOWN(phys_addr),
-+ vm_get_page_prot(page_prot_bits));
- if (ret != VM_FAULT_NOPAGE) {
- mutex_unlock(&encl->lock);
-
-@@ -336,15 +340,14 @@ static int sgx_encl_debug_write(struct sgx_encl *encl, struct sgx_encl_page *pag
- * Load an enclave page to EPC if required, and take encl->lock.
- */
- static struct sgx_encl_page *sgx_encl_reserve_page(struct sgx_encl *encl,
-- unsigned long addr,
-- unsigned long vm_flags)
-+ unsigned long addr)
- {
- struct sgx_encl_page *entry;
-
- for ( ; ; ) {
- mutex_lock(&encl->lock);
-
-- entry = sgx_encl_load_page(encl, addr, vm_flags);
-+ entry = sgx_encl_load_page(encl, addr);
- if (PTR_ERR(entry) != -EBUSY)
- break;
-
-@@ -380,8 +383,7 @@ static int sgx_vma_access(struct vm_area_struct *vma, unsigned long addr,
- return -EFAULT;
-
- for (i = 0; i < len; i += cnt) {
-- entry = sgx_encl_reserve_page(encl, (addr + i) & PAGE_MASK,
-- vma->vm_flags);
-+ entry = sgx_encl_reserve_page(encl, (addr + i) & PAGE_MASK);
- if (IS_ERR(entry)) {
- ret = PTR_ERR(entry);
- break;
---
-2.35.1
-