From patchwork Tue Mar 31 11:44:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11467633 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1347615AB for ; Tue, 31 Mar 2020 11:44:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EF99F208E0 for ; Tue, 31 Mar 2020 11:44:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730601AbgCaLon (ORCPT ); Tue, 31 Mar 2020 07:44:43 -0400 Received: from mga17.intel.com ([192.55.52.151]:15944 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730366AbgCaLon (ORCPT ); Tue, 31 Mar 2020 07:44:43 -0400 IronPort-SDR: OSPqXFkXqTJvuiN2DZgRp4BtwEAs8c4Bm1GX7Ftf7hyOnL+oCmKmvvx69RYKoADkttbfbipAvb KxiNDyHwVxlg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Mar 2020 04:44:43 -0700 IronPort-SDR: 3eMP/DmcO1bPzc7id5tY7e4Wz9QMOVZMZMIcn615ZODyBTAWhXPPTjAQ6DpUWqhs8k7qwyDxAX 1FFekoogMZdA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,327,1580803200"; d="scan'208";a="272717046" Received: from tking1-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.59.94]) by fmsmga004.fm.intel.com with ESMTP; 31 Mar 2020 04:44:40 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: kai.svahn@intel.com, bruce.schlobohm@intel.com, Jarkko Sakkinen , luto@kernel.org, Stephen Smalley , Casey Schaufler , Haitao Huang , Sean Christopherson Subject: [PATCH 1/4] x86/sgx: Remove PROT_NONE branch from sgx_encl_may_map(). Date: Tue, 31 Mar 2020 14:44:29 +0300 Message-Id: <20200331114432.7593-2-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> References: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org sgx_encl_may_map() always succeeding when PROT_NONE is given is not that useful behaviour as one can just well as do an anonymous mapping as demonstrated by the change in this patch to the test program. As a consequence, remove the special case. Pratically any possible way to make sure that you don't overwrite anything useful in the memory, should be fine. MAP_FIXED does not care what's underneath (if you want't it to care you ought to use MAP_FIXED_NO_REPLACE). After this change, the selftest run called sgx_mmap() only three times (TCS, text, data) instead of four. test_sgx-1811 [002] .... 586.907585: sgx_mmap <-mmap_region test_sgx-1811 [002] .... 586.911752: sgx_mmap <-mmap_region test_sgx-1811 [002] .... 586.911756: sgx_mmap <-mmap_region This also gives more angles to segregate enclave building and mapping as the mmap()'s need to be applied only when the enclave is fully built: Cc: luto@kernel.org Cc: Stephen Smalley Cc: Casey Schaufler Cc: Haitao Huang Cc: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- Documentation/x86/sgx.rst | 13 +++++-------- arch/x86/kernel/cpu/sgx/encl.c | 7 +------ arch/x86/kernel/cpu/sgx/ioctl.c | 5 ----- tools/testing/selftests/sgx/load.c | 3 ++- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/Documentation/x86/sgx.rst b/Documentation/x86/sgx.rst index 79de1f01aa5b..9609a3409ad1 100644 --- a/Documentation/x86/sgx.rst +++ b/Documentation/x86/sgx.rst @@ -168,14 +168,11 @@ accounted to the processes of which behalf the kernel happened to be acting on. Access control ============== -`mmap()` permissions are capped by the enclave permissions. The consequences of -this is are: - -1. Pages for a VMA must built before `mmap()` can be applied with the - permissions required for running the enclave. -2. An address range for an enclave can be reserved with a `PROT_NONE` mapping - (not required but usually makes sense to guarantee that the used address - range is available). +`mmap()` permissions are capped by the enclave permissions. A direct +consequence of this is that all the pages for an address range must be added +before `mmap()` can be applied. Effectively an enclave page with minimum +permission in the address range sets the permission cap for the mapping +operation. Usage Models ============ diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index d6a19bdd1921..e0124a2f22d5 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -288,8 +288,7 @@ static unsigned int sgx_vma_fault(struct vm_fault *vmf) * * Iterate through the enclave pages contained within [@start, @end) to verify * the permissions requested by @vm_prot_bits do not exceed that of any enclave - * page to be mapped. Page addresses that do not have an associated enclave - * page are interpreted to zero permissions. + * page to be mapped. * * Return: * 0 on success, @@ -308,10 +307,6 @@ int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start, if (!!(current->personality & READ_IMPLIES_EXEC)) return -EACCES; - /* PROT_NONE always succeeds. */ - if (!vm_prot_bits) - return 0; - idx_start = PFN_DOWN(start); idx_end = PFN_DOWN(end - 1); diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 12e1496f8a8b..3af0596530a8 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -481,15 +481,10 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long src, * * 1. A regular page: PROT_R, PROT_W and PROT_X match the SECINFO permissions. * 2. A TCS page: PROT_R | PROT_W. - * 3. No page: PROT_NONE. * * mmap() is not allowed to surpass the minimum of the maximum protection bits * within the given address range. * - * As stated above, a non-existent page is interpreted as a page with no - * permissions. In effect, this allows mmap() with PROT_NONE to be used to seek - * an address range for the enclave that can be then populated into SECS. - * * If ENCLS opcode fails, that effectively means that EPC has been invalidated. * When this happens the enclave is destroyed and -EIO is returned to the * caller. diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c index 35a2d7a47dd5..53c565347e9e 100644 --- a/tools/testing/selftests/sgx/load.c +++ b/tools/testing/selftests/sgx/load.c @@ -231,7 +231,8 @@ static bool encl_map_area(struct encl *encl) size_t encl_size = encl->encl_size; void *area; - area = mmap(NULL, encl_size * 2, PROT_NONE, MAP_SHARED, encl->fd, 0); + area = mmap(NULL, encl_size * 2, PROT_NONE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (area == MAP_FAILED) { perror("mmap"); return false; From patchwork Tue Mar 31 11:44:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11467637 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E679E17EF for ; Tue, 31 Mar 2020 11:44:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CFE0620848 for ; Tue, 31 Mar 2020 11:44:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730642AbgCaLot (ORCPT ); Tue, 31 Mar 2020 07:44:49 -0400 Received: from mga07.intel.com ([134.134.136.100]:45935 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730542AbgCaLot (ORCPT ); Tue, 31 Mar 2020 07:44:49 -0400 IronPort-SDR: HfFVOmP3xn8ijXeOQewJ7uPFRTHuxv6GTXLIPvfl3dxDjVrdw015nc/rzMuyyFBi7ffGpD4+xr Q47sfqvgEKSQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Mar 2020 04:44:48 -0700 IronPort-SDR: S36AzHGR9Nb+BXDuEFT3Ql9WYve7T1kjLSvwIzZ5kO+RNvMRpW/UfOBRDnJhKJeypCfdRIGlUJ ZowhcH2l5k+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,327,1580803200"; d="scan'208";a="272717070" Received: from tking1-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.59.94]) by fmsmga004.fm.intel.com with ESMTP; 31 Mar 2020 04:44:44 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: kai.svahn@intel.com, bruce.schlobohm@intel.com, Jarkko Sakkinen , luto@kernel.org, Stephen Smalley , Casey Schaufler , Haitao Huang , Sean Christopherson Subject: [PATCH 2/4] x86/sgx: Put enclaves into anonymous files Date: Tue, 31 Mar 2020 14:44:30 +0300 Message-Id: <20200331114432.7593-3-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> References: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org When creating an enclave attach it to an anonymous file. This prepares the code to have a separate interface at runtime, which can be published to the user space after the enclave has been fully initialized. Cc: luto@kernel.org Cc: Stephen Smalley Cc: Casey Schaufler Cc: Haitao Huang Cc: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/driver.c | 102 +++++++++++++++++++++---------- arch/x86/kernel/cpu/sgx/ioctl.c | 3 +- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c index 997a7f4117c5..1c825ef957db 100644 --- a/arch/x86/kernel/cpu/sgx/driver.c +++ b/arch/x86/kernel/cpu/sgx/driver.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "driver.h" #include "encl.h" @@ -21,35 +22,7 @@ u64 sgx_attributes_reserved_mask; u64 sgx_xfrm_reserved_mask = ~0x3; u32 sgx_xsave_size_tbl[64]; -static int sgx_open(struct inode *inode, struct file *file) -{ - struct sgx_encl *encl; - int ret; - - encl = kzalloc(sizeof(*encl), GFP_KERNEL); - if (!encl) - return -ENOMEM; - - atomic_set(&encl->flags, 0); - kref_init(&encl->refcount); - INIT_LIST_HEAD(&encl->va_pages); - INIT_RADIX_TREE(&encl->page_tree, GFP_KERNEL); - mutex_init(&encl->lock); - INIT_LIST_HEAD(&encl->mm_list); - spin_lock_init(&encl->mm_lock); - - ret = init_srcu_struct(&encl->srcu); - if (ret) { - kfree(encl); - return ret; - } - - file->private_data = encl; - - return 0; -} - -static int sgx_release(struct inode *inode, struct file *file) +static int sgx_encl_file_release(struct inode *inode, struct file *file) { struct sgx_encl *encl = file->private_data; struct sgx_encl_mm *encl_mm; @@ -84,6 +57,68 @@ static int sgx_release(struct inode *inode, struct file *file) return 0; } +static const struct file_operations sgx_encl_file_fops = { + .owner = THIS_MODULE, + .release = sgx_encl_file_release, +}; + +static int sgx_open(struct inode *inode, struct file *file) +{ + struct file *encl_file = NULL; + struct sgx_encl *encl = NULL; + int ret; + + encl = kzalloc(sizeof(*encl), GFP_KERNEL); + if (!encl) { + ret = -ENOMEM; + goto err; + } + + encl_file = anon_inode_getfile("[sgx]", &sgx_encl_file_fops, encl, + O_RDWR); + if (IS_ERR(encl_file)) { + ret = PTR_ERR(encl_file); + goto err; + } + + ret = init_srcu_struct(&encl->srcu); + if (ret) + goto err; + + atomic_set(&encl->flags, 0); + kref_init(&encl->refcount); + INIT_LIST_HEAD(&encl->va_pages); + INIT_RADIX_TREE(&encl->page_tree, GFP_KERNEL); + mutex_init(&encl->lock); + INIT_LIST_HEAD(&encl->mm_list); + spin_lock_init(&encl->mm_lock); + + file->private_data = encl_file; + + return 0; + +err: + if (encl_file) + fput(encl_file); + + kfree(encl); + return ret; +} + +static int sgx_encl_dev_release(struct inode *inode, struct file *file) +{ + struct file *encl_file = file->private_data; + + /* + * Can be NULL when the enclave file has been handed over to the + * user space. + */ + if (encl_file) + fput(encl_file); + + return 0; +} + #ifdef CONFIG_COMPAT static long sgx_compat_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) @@ -94,7 +129,8 @@ static long sgx_compat_ioctl(struct file *filep, unsigned int cmd, static int sgx_mmap(struct file *file, struct vm_area_struct *vma) { - struct sgx_encl *encl = file->private_data; + struct file *encl_file = file->private_data; + struct sgx_encl *encl = encl_file->private_data; int ret; ret = sgx_encl_may_map(encl, vma->vm_start, vma->vm_end, @@ -128,10 +164,10 @@ static unsigned long sgx_get_unmapped_area(struct file *file, return current->mm->get_unmapped_area(file, addr, len, pgoff, flags); } -static const struct file_operations sgx_encl_fops = { +static const struct file_operations sgx_encl_dev_fops = { .owner = THIS_MODULE, .open = sgx_open, - .release = sgx_release, + .release = sgx_encl_dev_release, .unlocked_ioctl = sgx_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sgx_compat_ioctl, @@ -148,7 +184,7 @@ static struct miscdevice sgx_dev_enclave = { .minor = MISC_DYNAMIC_MINOR, .name = "enclave", .nodename = "sgx/enclave", - .fops = &sgx_encl_fops, + .fops = &sgx_encl_dev_fops, }; static struct miscdevice sgx_dev_provision = { diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 3af0596530a8..891aa9395907 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -766,7 +766,8 @@ static long sgx_ioc_enclave_set_attribute(struct sgx_encl *encl, long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { - struct sgx_encl *encl = filep->private_data; + struct file *encl_file = filep->private_data; + struct sgx_encl *encl = encl_file->private_data; int ret, encl_flags; encl_flags = atomic_fetch_or(SGX_ENCL_IOCTL, &encl->flags); From patchwork Tue Mar 31 11:44:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11467639 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 943A015AB for ; Tue, 31 Mar 2020 11:44:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C5D0206DB for ; Tue, 31 Mar 2020 11:44:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730628AbgCaLoy (ORCPT ); Tue, 31 Mar 2020 07:44:54 -0400 Received: from mga07.intel.com ([134.134.136.100]:45935 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730542AbgCaLoy (ORCPT ); Tue, 31 Mar 2020 07:44:54 -0400 IronPort-SDR: e7dyTjfoQMoTDcaOhhojmCJDB6VPtKOPenLPmnE5RPF5ewKpztUqmv3/DFS37vXZGM65bzeeA3 E4ELcxDGl3Ww== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Mar 2020 04:44:53 -0700 IronPort-SDR: lKAKF9h1iJakbREWouhbQpDCQsDjD5zgAD9n5KPIwlZeyIbX/a2GB519ph7fMcifY51zqj0/gI t8mUKGfCKp7g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,327,1580803200"; d="scan'208";a="272717087" Received: from tking1-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.59.94]) by fmsmga004.fm.intel.com with ESMTP; 31 Mar 2020 04:44:50 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: kai.svahn@intel.com, bruce.schlobohm@intel.com, Jarkko Sakkinen , luto@kernel.org, Stephen Smalley , Casey Schaufler , Haitao Huang , Sean Christopherson Subject: [PATCH 3/4] x86/sgx: Move mmap() to the anonymous enclave file Date: Tue, 31 Mar 2020 14:44:31 +0300 Message-Id: <20200331114432.7593-4-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> References: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org Move mmap() to the internal anonymous enclave file as the latest Linux distributions tend to map /dev as noexec. Consequences: 1. Building an enclave requires no special privileges as the device file has no operations to map the enclave to the address space. 2. Running an enclave requires execu-from-mem privilege as one needs to be able to map pages with execution rights. My conclusion is that exec-from-mem is the correct level of privileges for an enclave because it best represents the actual enclave behaviour. After this change the mmap()'s will fail expectedly with -ENODEV. Cc: luto@kernel.org Cc: Stephen Smalley Cc: Casey Schaufler Cc: Haitao Huang Cc: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/driver.c | 45 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c index 1c825ef957db..b871dbd1490f 100644 --- a/arch/x86/kernel/cpu/sgx/driver.c +++ b/arch/x86/kernel/cpu/sgx/driver.c @@ -57,9 +57,31 @@ static int sgx_encl_file_release(struct inode *inode, struct file *file) return 0; } +static int sgx_encl_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct sgx_encl *encl = file->private_data; + int ret; + + ret = sgx_encl_may_map(encl, vma->vm_start, vma->vm_end, + vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)); + if (ret) + return ret; + + ret = sgx_encl_mm_add(encl, vma->vm_mm); + if (ret) + return ret; + + vma->vm_ops = &sgx_vm_ops; + vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO; + vma->vm_private_data = encl; + + return 0; +} + static const struct file_operations sgx_encl_file_fops = { .owner = THIS_MODULE, .release = sgx_encl_file_release, + .mmap = sgx_encl_file_mmap, }; static int sgx_open(struct inode *inode, struct file *file) @@ -127,28 +149,6 @@ static long sgx_compat_ioctl(struct file *filep, unsigned int cmd, } #endif -static int sgx_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct file *encl_file = file->private_data; - struct sgx_encl *encl = encl_file->private_data; - int ret; - - ret = sgx_encl_may_map(encl, vma->vm_start, vma->vm_end, - vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)); - if (ret) - return ret; - - ret = sgx_encl_mm_add(encl, vma->vm_mm); - if (ret) - return ret; - - vma->vm_ops = &sgx_vm_ops; - vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO; - vma->vm_private_data = encl; - - return 0; -} - static unsigned long sgx_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, @@ -172,7 +172,6 @@ static const struct file_operations sgx_encl_dev_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = sgx_compat_ioctl, #endif - .mmap = sgx_mmap, .get_unmapped_area = sgx_get_unmapped_area, }; From patchwork Tue Mar 31 11:44:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11467641 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A77715AB for ; Tue, 31 Mar 2020 11:45:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 18336206DB for ; Tue, 31 Mar 2020 11:45:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730542AbgCaLpA (ORCPT ); Tue, 31 Mar 2020 07:45:00 -0400 Received: from mga07.intel.com ([134.134.136.100]:45954 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730515AbgCaLo7 (ORCPT ); Tue, 31 Mar 2020 07:44:59 -0400 IronPort-SDR: f00lKzajIQdKeAgHRmGySX4BGFdkp2VxzNO+UNua8SUlDDFwYRid1ul8/ztfk+l/Gmecq6pGhl 5A1h/T6qsK4g== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Mar 2020 04:44:59 -0700 IronPort-SDR: ycM7814PHdSS326X/foGVY2ZQ7W8RmBRDCEPFssyntvylsI8rrg1RQ9y4643PE5s4RgnKnEFGI zoJeT/3SlGnw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,327,1580803200"; d="scan'208";a="272717104" Received: from tking1-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.59.94]) by fmsmga004.fm.intel.com with ESMTP; 31 Mar 2020 04:44:55 -0700 From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: kai.svahn@intel.com, bruce.schlobohm@intel.com, Jarkko Sakkinen , luto@kernel.org, Stephen Smalley , Casey Schaufler , Haitao Huang , Sean Christopherson Subject: [PATCH 4/4] x86/sgx: Hand over the enclave file to the user space Date: Tue, 31 Mar 2020 14:44:32 +0300 Message-Id: <20200331114432.7593-5-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> References: <20200331114432.7593-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org Add a new output parameter, @enclave_fd, to struct sgx_enclave_init, which will receive a file descriptor pointing the enclave file whose ownership is transferred to the user space. While doing this, replace the comment prepending sgx_ioc_enclave_init() with a regular (not kdoc) comment given that it was out of date and the function is internal. Cc: luto@kernel.org Cc: Stephen Smalley Cc: Casey Schaufler Cc: Haitao Huang Cc: Sean Christopherson Signed-off-by: Jarkko Sakkinen --- arch/x86/include/uapi/asm/sgx.h | 2 ++ arch/x86/kernel/cpu/sgx/ioctl.c | 56 ++++++++++++++++++------------ tools/testing/selftests/sgx/load.c | 16 +++++---- tools/testing/selftests/sgx/main.c | 3 +- tools/testing/selftests/sgx/main.h | 3 +- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h index e196cfd44b70..62f990c0a295 100644 --- a/arch/x86/include/uapi/asm/sgx.h +++ b/arch/x86/include/uapi/asm/sgx.h @@ -60,9 +60,11 @@ struct sgx_enclave_add_pages { * struct sgx_enclave_init - parameter structure for the * %SGX_IOC_ENCLAVE_INIT ioctl * @sigstruct: address for the SIGSTRUCT data + * @enclave_fd: file handle of the enclave */ struct sgx_enclave_init { __u64 sigstruct; + __u64 enclave_fd; }; /** diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 891aa9395907..b25e18622c02 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -606,9 +606,11 @@ static int sgx_einit(struct sgx_sigstruct *sigstruct, void *token, return ret; } -static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, - void *token) +static int __sgx_ioc_enclave_init(struct file *filep, + struct sgx_sigstruct *sigstruct, void *token) { + struct file *encl_file = filep->private_data; + struct sgx_encl *encl = encl_file->private_data; u64 mrsigner[4]; int ret; int i; @@ -656,35 +658,39 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, sgx_encl_destroy(encl); ret = -EFAULT; + goto err_out; } else if (ret) { pr_debug("EINIT returned %d\n", ret); ret = -EPERM; - } else { - atomic_or(SGX_ENCL_INITIALIZED, &encl->flags); + goto err_out; } + /* Transfer the ownership of the enclave file to the user space. */ + ret = get_unused_fd_flags(O_RDWR); + if (ret < 0) + goto err_out; + + filep->private_data = NULL; + fd_install(ret, encl_file); + + atomic_or(SGX_ENCL_INITIALIZED, &encl->flags); + err_out: mutex_unlock(&encl->lock); return ret; } -/** - * sgx_ioc_enclave_init - handler for %SGX_IOC_ENCLAVE_INIT - * - * @filep: open file to /dev/sgx - * @arg: userspace pointer to a struct sgx_enclave_init instance - * - * Flush any outstanding enqueued EADD operations and perform EINIT. The - * Launch Enclave Public Key Hash MSRs are rewritten as necessary to match - * the enclave's MRSIGNER, which is caculated from the provided sigstruct. - * - * Return: - * 0 on success, - * SGX error code on EINIT failure, - * -errno otherwise +/* + * Initialize the enclave by performing ENCLS[EINIT] and hand over the enclave + * file to the user space. The function also checks whether the LE public key + * hash MSRs are out of date and updates them as necessary before performing + * ENCLS[EINIT]. */ -static long sgx_ioc_enclave_init(struct sgx_encl *encl, void __user *arg) +static long sgx_ioc_enclave_init(struct file *filep, + struct sgx_enclave_init __user *arg) { + struct file *encl_file = filep->private_data; + struct sgx_encl *encl = encl_file->private_data; struct sgx_sigstruct *sigstruct; struct sgx_enclave_init einit; struct page *initp_page; @@ -708,12 +714,16 @@ static long sgx_ioc_enclave_init(struct sgx_encl *encl, void __user *arg) if (copy_from_user(sigstruct, (void __user *)einit.sigstruct, sizeof(*sigstruct))) { ret = -EFAULT; - goto out; + goto err; } - ret = sgx_encl_init(encl, sigstruct, token); + ret = __sgx_ioc_enclave_init(filep, sigstruct, token); + if (ret < 0) + goto err; -out: + ret = put_user((uint64_t)ret, &arg->enclave_fd); + +err: kunmap(initp_page); __free_page(initp_page); return ret; @@ -785,7 +795,7 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) ret = sgx_ioc_enclave_add_pages(encl, (void __user *)arg); break; case SGX_IOC_ENCLAVE_INIT: - ret = sgx_ioc_enclave_init(encl, (void __user *)arg); + ret = sgx_ioc_enclave_init(filep, (void __user *)arg); break; case SGX_IOC_ENCLAVE_SET_ATTRIBUTE: ret = sgx_ioc_enclave_set_attribute(encl, (void __user *)arg); diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c index 53c565347e9e..ee5792f98162 100644 --- a/tools/testing/selftests/sgx/load.c +++ b/tools/testing/selftests/sgx/load.c @@ -27,8 +27,11 @@ void encl_delete(struct encl *encl) if (encl->bin) munmap(encl->bin, encl->bin_size); - if (encl->fd) - close(encl->fd); + if (encl->encl_fd) + close(encl->encl_fd); + + if (encl->dev_fd) + close(encl->dev_fd); if (encl->segment_tbl) free(encl->segment_tbl); @@ -88,7 +91,7 @@ static bool encl_ioc_create(struct encl *encl) secs->size = encl->encl_size; ioc.src = (unsigned long)secs; - rc = ioctl(encl->fd, SGX_IOC_ENCLAVE_CREATE, &ioc); + rc = ioctl(encl->dev_fd, SGX_IOC_ENCLAVE_CREATE, &ioc); if (rc) { fprintf(stderr, "SGX_IOC_ENCLAVE_CREATE failed: errno=%d\n", errno); @@ -114,7 +117,7 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg) ioc.secinfo = (unsigned long)&secinfo; ioc.flags = SGX_PAGE_MEASURE; - rc = ioctl(encl->fd, SGX_IOC_ENCLAVE_ADD_PAGES, &ioc); + rc = ioctl(encl->dev_fd, SGX_IOC_ENCLAVE_ADD_PAGES, &ioc); if (rc) { fprintf(stderr, "SGX_IOC_ENCLAVE_ADD_PAGES failed: errno=%d.\n", errno); @@ -145,7 +148,7 @@ bool encl_load(const char *path, struct encl *encl) goto err; } - encl->fd = ret; + encl->dev_fd = ret; if (!encl_map_bin(path, encl)) goto err; @@ -271,12 +274,13 @@ bool encl_build(struct encl *encl) } ioc.sigstruct = (uint64_t)&encl->sigstruct; - ret = ioctl(encl->fd, SGX_IOC_ENCLAVE_INIT, &ioc); + ret = ioctl(encl->dev_fd, SGX_IOC_ENCLAVE_INIT, &ioc); if (ret) { fprintf(stderr, "SGX_IOC_ENCLAVE_INIT failed: errno=%d\n", errno); return false; } + encl->encl_fd = ioc.enclave_fd; return true; } diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c index 9238cce47f77..17bf57909435 100644 --- a/tools/testing/selftests/sgx/main.c +++ b/tools/testing/selftests/sgx/main.c @@ -149,7 +149,8 @@ int main(int argc, char *argv[], char *envp[]) struct encl_segment *seg = &encl.segment_tbl[i]; addr = mmap((void *)encl.encl_base + seg->offset, seg->size, - seg->prot, MAP_SHARED | MAP_FIXED, encl.fd, 0); + seg->prot, MAP_SHARED | MAP_FIXED, encl.encl_fd, + 0); if (addr == MAP_FAILED) { fprintf(stderr, "mmap() failed, errno=%d.\n", errno); return false; diff --git a/tools/testing/selftests/sgx/main.h b/tools/testing/selftests/sgx/main.h index 6e1ae292bd25..cf0d4cf20fb0 100644 --- a/tools/testing/selftests/sgx/main.h +++ b/tools/testing/selftests/sgx/main.h @@ -14,7 +14,8 @@ struct encl_segment { }; struct encl { - int fd; + int dev_fd; + int encl_fd; void *bin; off_t bin_size; void *src;