From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1202EC5519F for ; Thu, 12 Nov 2020 22:04:11 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 7F61D22227 for ; Thu, 12 Nov 2020 22:04:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="CCDUh9uZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7F61D22227 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id F332B6B0068; Thu, 12 Nov 2020 17:04:09 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id EBE296B006C; Thu, 12 Nov 2020 17:04:09 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D832F6B006E; Thu, 12 Nov 2020 17:04:09 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0203.hostedemail.com [216.40.44.203]) by kanga.kvack.org (Postfix) with ESMTP id 9F9026B0068 for ; Thu, 12 Nov 2020 17:04:09 -0500 (EST) Received: from smtpin26.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 44B151EE6 for ; Thu, 12 Nov 2020 22:04:09 +0000 (UTC) X-FDA: 77477145018.26.fly21_04087e427309 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin26.hostedemail.com (Postfix) with ESMTP id F010F1804B640 for ; Thu, 12 Nov 2020 22:04:08 +0000 (UTC) X-HE-Tag: fly21_04087e427309 X-Filterd-Recvd-Size: 6284 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf40.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 22:04:07 +0000 (UTC) Received: from suppilovahvero.lan (83-245-197-237.elisa-laajakaista.fi [83.245.197.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 24C072224A; Thu, 12 Nov 2020 22:04:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605218647; bh=3uE1EWWgmHyhxsMrlxMO0pitcKAQZZowQalmf1U/uhQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CCDUh9uZxRU9CDY8IukXlxMH6jlh1+xh8Kr03XmvLubN0b6kXGpf1mUr0CQaERU8b 1jBZHUUbRU1OPaJmdkvAj/0niyprFTxvWNHarA7ujNDemOJdTwgmpaMOvfz+gbq1NS iX8RvRPS1YtFFpBVEmiURT6aA7DTEhQnfdD1J92I= From: Jarkko Sakkinen To: x86@kernel.org, linux-sgx@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jarkko Sakkinen , linux-mm@kvack.org, Andrew Morton , Matthew Wilcox , Jethro Beekman , andriy.shevchenko@linux.intel.com, asapek@google.com, bp@alien8.de, cedric.xing@intel.com, chenalexchen@google.com, conradparker@google.com, cyhanish@google.com, dave.hansen@intel.com, haitao.huang@intel.com, kai.huang@intel.com, kai.svahn@intel.com, kmoy@google.com, ludloff@google.com, luto@kernel.org, nhorman@redhat.com, npmccallum@redhat.com, puiterwijk@redhat.com, rientjes@google.com, sean.j.christopherson@intel.com, tglx@linutronix.de, yaozhangx@google.com, mikko.ylinen@intel.com Subject: [PATCH v41 22/24] x86/sgx: Add ptrace() support for the SGX driver Date: Fri, 13 Nov 2020 00:01:33 +0200 Message-Id: <20201112220135.165028-23-jarkko@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201112220135.165028-1-jarkko@kernel.org> References: <20201112220135.165028-1-jarkko@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Enclave memory is normally inaccessible from outside the enclave. This makes enclaves hard to debug. However, enclaves can be put in a debug mo= de when they are being built. In debug enclaves data *can* be read and/or written by using the ENCLS[EDBGRD] and ENCLS[EDBGWR] functions. This is obviously only for debugging and destroys all the protections afforded to normal enclaves. But, enclaves know their own debug status a= nd can adjust their behavior appropriately. Add a vm_ops->access() implementation which can be used to read and write memory inside debug enclaves. This is typically used via ptrace() APIs. Cc: linux-mm@kvack.org Cc: Andrew Morton Cc: Matthew Wilcox Tested-by: Jethro Beekman # v40 Signed-off-by: Jarkko Sakkinen --- Changes from v39: * Check only for SGX_ENCL_DEBUG in sgx_vma_access(), so that a debug enclave's memory can read and written at any phase of its life-cycle. arch/x86/kernel/cpu/sgx/encl.c | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/enc= l.c index 141424657718..94e7e41e6adf 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -272,10 +272,121 @@ static int sgx_vma_mprotect(struct vm_area_struct = *vma, unsigned long start, return sgx_encl_may_map(vma->vm_private_data, start, end, newflags); } =20 +static int sgx_encl_debug_read(struct sgx_encl *encl, struct sgx_encl_pa= ge *page, + unsigned long addr, void *data) +{ + unsigned long offset =3D addr & ~PAGE_MASK; + int ret; + + + ret =3D __edbgrd(sgx_get_epc_virt_addr(page->epc_page) + offset, data); + if (ret) + return -EIO; + + return 0; +} + +static int sgx_encl_debug_write(struct sgx_encl *encl, struct sgx_encl_p= age *page, + unsigned long addr, void *data) +{ + unsigned long offset =3D addr & ~PAGE_MASK; + int ret; + + ret =3D __edbgwr(sgx_get_epc_virt_addr(page->epc_page) + offset, data); + if (ret) + return -EIO; + + return 0; +} + +/* + * Load an enclave page to EPC if required, and take encl->lock. + */ +static struct sgx_encl_page *sgx_encl_reserve_page(struct sgx_encl *encl= , + unsigned long addr, + unsigned long vm_flags) +{ + struct sgx_encl_page *entry; + + for ( ; ; ) { + mutex_lock(&encl->lock); + + entry =3D sgx_encl_load_page(encl, addr, vm_flags); + if (PTR_ERR(entry) !=3D -EBUSY) + break; + + mutex_unlock(&encl->lock); + } + + if (IS_ERR(entry)) + mutex_unlock(&encl->lock); + + return entry; +} + +static int sgx_vma_access(struct vm_area_struct *vma, unsigned long addr= , + void *buf, int len, int write) +{ + struct sgx_encl *encl =3D vma->vm_private_data; + struct sgx_encl_page *entry =3D NULL; + char data[sizeof(unsigned long)]; + unsigned long align; + int offset; + int cnt; + int ret =3D 0; + int i; + + /* + * If process was forked, VMA is still there but vm_private_data is set + * to NULL. + */ + if (!encl) + return -EFAULT; + + if (!test_bit(SGX_ENCL_DEBUG, &encl->flags)) + return -EFAULT; + + for (i =3D 0; i < len; i +=3D cnt) { + entry =3D sgx_encl_reserve_page(encl, (addr + i) & PAGE_MASK, + vma->vm_flags); + if (IS_ERR(entry)) { + ret =3D PTR_ERR(entry); + break; + } + + align =3D ALIGN_DOWN(addr + i, sizeof(unsigned long)); + offset =3D (addr + i) & (sizeof(unsigned long) - 1); + cnt =3D sizeof(unsigned long) - offset; + cnt =3D min(cnt, len - i); + + ret =3D sgx_encl_debug_read(encl, entry, align, data); + if (ret) + goto out; + + if (write) { + memcpy(data + offset, buf + i, cnt); + ret =3D sgx_encl_debug_write(encl, entry, align, data); + if (ret) + goto out; + } else { + memcpy(buf + i, data + offset, cnt); + } + +out: + mutex_unlock(&encl->lock); + + if (ret) + break; + } + + return ret < 0 ? ret : i; +} + const struct vm_operations_struct sgx_vm_ops =3D { .fault =3D sgx_vma_fault, .mprotect =3D sgx_vma_mprotect, .open =3D sgx_vma_open, + .access =3D sgx_vma_access, }; =20 /** --=20 2.27.0