[PATCH] Unconditionally block mprotect of enclave memory.

From: Dr. Greg
Date: Thu Nov 12 2020 - 05:48:57 EST


In SGX there are two levels of memory protection, the classic
page table mechanism and SGX hardware based page protections
that are codified in the Enclave Page Cache Metadata. A
successful memory access requires that both mechanisms agree
that the access is permitted.

In the initial implementation of SGX (SGX1), the page permissions
are immutable after the enclave is initialized. Even if classic
page protections are modified via mprotect, any attempt to access
enclave memory with alternative permissions will be blocked.

One of the architectural changes implemented in the second
generation of SGX (SGX2) is the ability for page access
permissions to be dynamically manipulated after the enclave is
initialized. This requires coordination between trusted code
running in the enclave and untrusted code using mprotect and
special ring-0 instructions.

One of the security threats associated with SGX2 hardware is that
enclave based code can conspire with its untrusted runtime to make
executable enclave memory writable. This provides the opportunity for
completely anonymous code execution that the operating system has no
visibility into.

All that is needed to, simply, close this vulnerability is to
eliminate the ability to call mprotect against the virtual memory
range of an enclave after it is initialized. Any mprotect changes
made prior to initialization that are inconsistent with the
permissions codified in the enclave will cause initialization and/or
access to fail.

Tested-by: Dr. Greg <greg@xxxxxxxxxxxx>
Signed-off-by: Dr. Greg <greg@xxxxxxxxxxxx>
---
arch/x86/kernel/cpu/sgx/encl.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
index 139f8c398685..c613482ebb56 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
@@ -270,11 +270,10 @@ static int sgx_vma_mprotect(struct vm_area_struct *vma,
struct vm_area_struct **pprev, unsigned long start,
unsigned long end, unsigned long newflags)
{
- int ret;
+ struct sgx_encl *encl = vma->vm_private_data;

- ret = sgx_encl_may_map(vma->vm_private_data, start, end, newflags);
- if (ret)
- return ret;
+ if ( test_bit(SGX_ENCL_INITIALIZED, &encl->flags) )
+ return -EACCES;

return mprotect_fixup(vma, pprev, start, end, newflags);
}
--
2.19.2


And here (demonstrating my age). ------------------------------------------

As always,
Dr. Greg Wettstein, Ph.D, Worker Autonomously self-defensive
Enjellic Systems Development, LLC IOT platforms and edge devices.
4206 N. 19th Ave.
Fargo, ND 58102
PH: 701-281-1686 EMAIL: greg@xxxxxxxxxxxx
------------------------------------------------------------------------------
"Umm.. the developers behind Flame were able to hijack Windows update,
gain access to a Microsoft code signing and website signing key while
staying undetected in the wild for at least 2+ years.

But System Restore 2.0 is going to stop them? Your average piece of
malware can survive a system restore..."
-- Slashdot