From patchwork Thu Oct 10 22:55:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 11184547 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 D5AB614ED for ; Thu, 10 Oct 2019 22:55:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C0CFA20B7C for ; Thu, 10 Oct 2019 22:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726653AbfJJWzj (ORCPT ); Thu, 10 Oct 2019 18:55:39 -0400 Received: from mga06.intel.com ([134.134.136.31]:20137 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726616AbfJJWzj (ORCPT ); Thu, 10 Oct 2019 18:55:39 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Oct 2019 15:55:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,281,1566889200"; d="scan'208";a="197400454" Received: from sjchrist-coffee.jf.intel.com ([10.54.74.41]) by orsmga003.jf.intel.com with ESMTP; 10 Oct 2019 15:55:38 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org Subject: [PATCH for_v23 3/4] x86/sgx: Fix EEXTEND error handling Date: Thu, 10 Oct 2019 15:55:29 -0700 Message-Id: <20191010225530.26400-4-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20191010225530.26400-1-sean.j.christopherson@intel.com> References: <20191010225530.26400-1-sean.j.christopherson@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 Rework EEXTEND error handling to fix issues related to destroying the enclave in response to EEXTEND failure. At the time of EEXTEND, the page is already visibile in the sense that it has been added to the radix tree, and therefore will be processed by sgx_encl_destroy(). This means the "add" part needs to be fully completed prior to invoking sgx_encl_destroy() in order to avoid consuming half-baked state. Move sgx_encl_destroy() to the call site of __sgx_encl_extend() so that it is somewhat more obvious why the add needs to complete before doing EEXTEND. Signed-off-by: Sean Christopherson --- arch/x86/kernel/cpu/sgx/ioctl.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 61a2a7b6677e..fd4117f18564 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -351,18 +351,14 @@ static int __sgx_encl_extend(struct sgx_encl *encl, for_each_set_bit(i, &mrmask, 16) { ret = __eextend(sgx_epc_addr(encl->secs.epc_page), sgx_epc_addr(epc_page) + (i * 0x100)); - if (ret) - goto err_out; + if (ret) { + if (encls_failed(ret)) + ENCLS_WARN(ret, "EEXTEND"); + return -EFAULT; + } } return 0; - -err_out: - if (encls_failed(ret)) - ENCLS_WARN(ret, "EEXTEND"); - - sgx_encl_destroy(encl); - return -EFAULT; } static int sgx_encl_add_page(struct sgx_encl *encl, @@ -415,19 +411,24 @@ static int sgx_encl_add_page(struct sgx_encl *encl, if (ret) goto err_out; - ret = __sgx_encl_extend(encl, epc_page, addp->mrmask); - if (ret) - goto err_out; - + /* + * Complete the "add" before doing the "extend" so that the "add" + * isn't in a half-baked state in the extremely unlikely scenario the + * the enclave will be destroyed in response to EEXTEND failure. + */ encl_page->encl = encl; encl_page->epc_page = epc_page; encl->secs_child_cnt++; - sgx_mark_page_reclaimable(encl_page->epc_page); + ret = __sgx_encl_extend(encl, epc_page, addp->mrmask); + if (ret) + sgx_encl_destroy(encl); + else + sgx_mark_page_reclaimable(encl_page->epc_page); mutex_unlock(&encl->lock); up_read(¤t->mm->mmap_sem); - return 0; + return ret; err_out: radix_tree_delete(&encl_page->encl->page_tree,