Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1813107pxk; Fri, 2 Oct 2020 21:55:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz/L89zF0H1m2QqHeZ3NBzBrzePX5fGTu+b4/2NXabxzKfx7T2Mwh760tB7gAGHb7IjjyON X-Received: by 2002:a17:906:a156:: with SMTP id bu22mr5393762ejb.177.1601700912301; Fri, 02 Oct 2020 21:55:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601700912; cv=none; d=google.com; s=arc-20160816; b=jLJuwPM3l8TYff3BjG2JWpFexFD3oGHZCcUTvtZG+sfp2pXOscP8ffXRxHD0onbFi9 UNgTRFl6fs6pQap7xSjlSlD6/HcO1iSBph0Msw05N4jaQaNqGb1k19gGufGPxKPWlhqr BVHjZ9ypCguxEeLwHq94AVw/MsjvoB0VRiJJM6PcfpdpIWCTUifhpHxZi/AyGa3S3xvy ZjzwWodomwwSZFa5NQor3qbPkh47OoIMc3h6jeLHCmK3KqrVbxUYWc3ScYOK68xgQg6a 9RoLOobMnRsdf/u5n6sTOtCDpUmx223X7H7gXJeBUNE8HiNqgq1Sv32G1DlK36WLEngt l/ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Y81Q/7zzj7T4P4h69W2xnbylNS5k4ngX31wzy7Z6tOk=; b=pA/frBBGGQ44aR4AWKcseHzWsmmy+YR7wyOXOm5yE4fwyTnnU7/SEVnVyUiW9s6ord mtQXgal14BXL7Z48JGqaqi1OlMMnsJ2hvrlF1swKA7f6Du+BZwaKEYeKFLsCBR7oUGLp 5bqAVReRFm9VHD9IKH3CkLCYNyof/F0V/zYzjyVJ33z3jYvHUjaO9pHci6EejiER9BhZ i3dHwWbfg8paP8Z9YkMrs5uuKypTz6gsV8ifOo7FgyVKlUTrTqIxB0wi5+H8k1FnO70n vcYVCn+QL7RTQVIqDqQtACZ38/rOBeg7eHyT/kEoy2V2TYnMErBOLeoiowWKzeuz+OJn lBdA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y2si1164976edw.497.2020.10.02.21.54.50; Fri, 02 Oct 2020 21:55:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726049AbgJCEwY (ORCPT + 99 others); Sat, 3 Oct 2020 00:52:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:52932 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725770AbgJCEvw (ORCPT ); Sat, 3 Oct 2020 00:51:52 -0400 Received: from localhost (83-245-197-237.elisa-laajakaista.fi [83.245.197.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 749FE22262; Sat, 3 Oct 2020 04:51:43 +0000 (UTC) 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 v39 17/24] x86/sgx: Add ptrace() support for the SGX driver Date: Sat, 3 Oct 2020 07:50:52 +0300 Message-Id: <20201003045059.665934-18-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201003045059.665934-1-jarkko.sakkinen@linux.intel.com> References: <20201003045059.665934-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Intel Sofware Guard eXtensions (SGX) allows creation of executable blobs called enclaves, which cannot be accessed by default when not executing inside the enclave. Enclaves can be entered by only using predefined memory addresses, which are defined when the enclave is loaded. However, enclaves can defined as debug enclaves at the load time. In debug enclaves data can be read and/or written a memory word at a time by by using ENCLS[EDBGRD] and ENCLS[EDBGWR] leaf instructions. Add sgx_vma_access() function that implements 'access' virtual function of struct vm_operations_struct. Use aforementioned leaf instructions to provide read and write primitives for the enclave memory. Cc: linux-mm@kvack.org Cc: Andrew Morton Cc: Matthew Wilcox Acked-by: Jethro Beekman Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/encl.c | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index 54326efa6c2f..ae45f8f0951e 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -337,10 +337,99 @@ static int sgx_vma_mprotect(struct vm_area_struct *vma, return mprotect_fixup(vma, pprev, start, end, newflags); } +static int sgx_encl_debug_read(struct sgx_encl *encl, struct sgx_encl_page *page, + unsigned long addr, void *data) +{ + unsigned long offset = addr & ~PAGE_MASK; + int ret; + + + ret = __edbgrd(sgx_get_epc_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_page *page, + unsigned long addr, void *data) +{ + unsigned long offset = addr & ~PAGE_MASK; + int ret; + + ret = __edbgwr(sgx_get_epc_addr(page->epc_page) + offset, data); + if (ret) + return -EIO; + + return 0; +} + +static int sgx_vma_access(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write) +{ + struct sgx_encl *encl = vma->vm_private_data; + struct sgx_encl_page *entry = NULL; + char data[sizeof(unsigned long)]; + unsigned long align; + unsigned int flags; + int offset; + int cnt; + int ret = 0; + int i; + + /* + * If process was forked, VMA is still there but vm_private_data is set + * to NULL. + */ + if (!encl) + return -EFAULT; + + flags = atomic_read(&encl->flags); + + if (!(flags & SGX_ENCL_DEBUG) || !(flags & SGX_ENCL_INITIALIZED) || + (flags & SGX_ENCL_DEAD)) + return -EFAULT; + + for (i = 0; i < len; i += cnt) { + entry = sgx_encl_reserve_page(encl, (addr + i) & PAGE_MASK); + if (IS_ERR(entry)) { + ret = PTR_ERR(entry); + break; + } + + align = ALIGN_DOWN(addr + i, sizeof(unsigned long)); + offset = (addr + i) & (sizeof(unsigned long) - 1); + cnt = sizeof(unsigned long) - offset; + cnt = min(cnt, len - i); + + ret = sgx_encl_debug_read(encl, entry, align, data); + if (ret) + goto out; + + if (write) { + memcpy(data + offset, buf + i, cnt); + ret = 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 = { .open = sgx_vma_open, .fault = sgx_vma_fault, .mprotect = sgx_vma_mprotect, + .access = sgx_vma_access, }; /** -- 2.25.1