Do not allow an enclave page to be mapped with PROT_EXEC if the source page is backed by a file on a noexec file system. Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx> --- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index c30acd3fbbdd..5f71be7cbb01 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -576,6 +576,27 @@ static int __sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, return ret; } +static int sgx_encl_page_protect(unsigned long src, unsigned long prot, + unsigned long *allowed_prot) +{ + struct vm_area_struct *vma; + + if (!(*allowed_prot & VM_EXEC)) + goto do_check; + + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, src); + if (!vma || (vma->vm_file && path_noexec(&vma->vm_file->f_path))) + *allowed_prot &= ~VM_EXEC; + up_read(¤t->mm->mmap_sem); + +do_check: + if (prot & ~*allowed_prot) + return -EACCES; + + return 0; +} + static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, unsigned long src, struct sgx_secinfo *secinfo, unsigned int mrmask, unsigned int flags) @@ -589,8 +610,9 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, BUILD_BUG_ON(SGX_SECINFO_R != VM_READ || SGX_SECINFO_W != VM_WRITE || SGX_SECINFO_X != VM_EXEC); - if (prot & ~allowed_prot) - return -EACCES; + ret = sgx_encl_page_protect(src, prot, &allowed_prot); + if (ret) + return ret; data_page = alloc_page(GFP_HIGHUSER); if (!data_page) -- 2.21.0