Message ID | 20190619222401.14942-7-sean.j.christopherson@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | security: x86/sgx: SGX vs. LSM | expand |
On Wed, Jun 19, 2019 at 03:23:55PM -0700, Sean Christopherson wrote: > SGX will use ->may_mprotect() to invoke an SGX variant of the existing > file_mprotect() and mmap_file() LSM hooks. > > The name may_mprotect() is intended to reflect the hook's purpose as a > way to restrict mprotect() as opposed to a wholesale replacement. > > Due to the nature of SGX and its Enclave Page Cache (EPC), all enclave > VMAs are backed by a single file, i.e. /dev/sgx/enclave, that must be > MAP_SHARED. Furthermore, all enclaves need read, write and execute > VMAs. As a result, applying W^X restrictions on /dev/sgx/enclave using > existing LSM hooks is for all intents and purposes impossible, e.g. > denying either W or X would deny access to *any* enclave. > > By hooking mprotect(), SGX can invoke an SGX specific LSM hook, which in > turn allows LSMs to enforce W^X policies. > > Alternatively, SGX could provide a helper to identify enclaves given a > vma or file. LSMs could then check if a mapping is for enclave and take > action according. > > A second alternative would be to have SGX implement its own LSM hooks > for file_mprotect() and mmap_file(), using them to "forward" the call to > the SGX specific hook. > > The major con to both alternatives is that they provide zero flexibility > for the SGX specific LSM hook. The "is_sgx_enclave()" helper doesn't > allow SGX can't supply any additional information whatsoever, and the > mmap_file() hook is called before the final address is known, e.g. SGX > can't provide any information about the specific enclave being mapped. > > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Absolutely nothing to say about this one. We can take it as part of the main patch set as it is. Not going to apply it though before the things have been sorted out. /Jarkko
diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e8834ac32b7..b11ec420c8d7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -458,6 +458,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 bf38dfbbb4b4..18732543b295 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -547,13 +547,20 @@ static int do_mprotect_pkey(unsigned long start, size_t len, goto out; } - error = security_file_mprotect(vma, reqprot, prot); - if (error) - 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; + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); if (error) goto out;
SGX will use ->may_mprotect() to invoke an SGX variant of the existing file_mprotect() and mmap_file() LSM hooks. The name may_mprotect() is intended to reflect the hook's purpose as a way to restrict mprotect() as opposed to a wholesale replacement. Due to the nature of SGX and its Enclave Page Cache (EPC), all enclave VMAs are backed by a single file, i.e. /dev/sgx/enclave, that must be MAP_SHARED. Furthermore, all enclaves need read, write and execute VMAs. As a result, applying W^X restrictions on /dev/sgx/enclave using existing LSM hooks is for all intents and purposes impossible, e.g. denying either W or X would deny access to *any* enclave. By hooking mprotect(), SGX can invoke an SGX specific LSM hook, which in turn allows LSMs to enforce W^X policies. Alternatively, SGX could provide a helper to identify enclaves given a vma or file. LSMs could then check if a mapping is for enclave and take action according. A second alternative would be to have SGX implement its own LSM hooks for file_mprotect() and mmap_file(), using them to "forward" the call to the SGX specific hook. The major con to both alternatives is that they provide zero flexibility for the SGX specific LSM hook. The "is_sgx_enclave()" helper doesn't allow SGX can't supply any additional information whatsoever, and the mmap_file() hook is called before the final address is known, e.g. SGX can't provide any information about the specific enclave being mapped. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- include/linux/mm.h | 2 ++ mm/mprotect.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-)