Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4696448imu; Tue, 18 Dec 2018 21:30:29 -0800 (PST) X-Google-Smtp-Source: AFSGD/Xmm9pwy/n3Albx9N+XVDPVlHqFnBEXLOxwf6Yc6u9quQooXYRBXrf2p0IHUwF9NucWz1lc X-Received: by 2002:a62:fb07:: with SMTP id x7mr19132022pfm.71.1545197429409; Tue, 18 Dec 2018 21:30:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545197429; cv=none; d=google.com; s=arc-20160816; b=lmn6qVNsREL7vw89e6q9vtHBwOPdCGcvLPZZZBttNXzorsBC7xrinXRasogY2Qmvua 7CiwHtJ+I8GFFesGTvaRNRT9nit+nE8fxdlM3HPmKSKTiOW+gWXorbYp//TC25Aix+6d 0ONsonHDR/dmOZyH/YegGT12AlwsZ9Ux6xBHWm1CKapUvnnZPfetEgExOHgpdKiyC4Ht 6JlhtMA6CImTahuXqDUo2Dmj7QoxZB0PvNMN72NEczjg9qOrzAkI3C02anVX5muzNrtN qjfAJOJASO10OY0cdBEWf6BgWdQF2jR84Adi5wWz42204ucYpMI1LUMM5pJ6GMh3Htzb LVHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:organization:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=WDB79G9lrFuzB0ACa294BUPmF/kJwwGR+Ld0y8gizb4=; b=GIMOmDZjKHKMBdyMQFuimkStWHR0OSQvoXznE469jwa/9XsIDwv7c309iWqXmlCPS+ UERqp9krdsRZ2BBn/NWDxY1gJN1OBt44bLRwP7CCGqkWvm0n1r8xdBwN9prpQf8htqPz ZjtQNOIWsvHV5i/xxcUu2xxfKduhs/imjadw1RCV5ikWPttZTJOwquJ8tT9z4PvhCuVL teITnRgzf31Lt5mWIq0VZ/LXpwCYFYsX9FCbol7V9E+sYwM5cE1lEMJTsaMrA51VMX2J b50uB9QdLeGbFFmq6asJg78LyX2KK8RZkCWrqRpQr3yVmm13S7Rg0RrpvhHjt8IFiqzD 7Pxg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id 197si14716927pgb.564.2018.12.18.21.30.13; Tue, 18 Dec 2018 21:30:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S1727641AbeLSFWK (ORCPT + 99 others); Wed, 19 Dec 2018 00:22:10 -0500 Received: from mga05.intel.com ([192.55.52.43]:2781 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726833AbeLSFWJ (ORCPT ); Wed, 19 Dec 2018 00:22:09 -0500 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2018 21:22:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,371,1539673200"; d="scan'208";a="102633722" Received: from cqinghon-mobl2.ccr.corp.intel.com (HELO localhost) ([10.249.254.218]) by orsmga008.jf.intel.com with ESMTP; 18 Dec 2018 21:22:01 -0800 Date: Wed, 19 Dec 2018 07:22:00 +0200 From: Jarkko Sakkinen To: Andy Lutomirski Cc: X86 ML , Platform Driver , linux-sgx@vger.kernel.org, Dave Hansen , "Christopherson, Sean J" , nhorman@redhat.com, npmccallum@redhat.com, "Ayoun, Serge" , shay.katz-zamir@intel.com, Haitao Huang , Andy Shevchenko , Thomas Gleixner , "Svahn, Kai" , mark.shanahan@intel.com, Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Darren Hart , Andy Shevchenko , "open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)" Subject: Re: [PATCH v17 18/23] platform/x86: Intel SGX driver Message-ID: <20181219052200.GA14909@linux.intel.com> References: <20181116010412.23967-1-jarkko.sakkinen@linux.intel.com> <20181116010412.23967-19-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Dec 17, 2018 at 09:55:08PM -0800, Andy Lutomirski wrote: > On Thu, Nov 15, 2018 at 5:08 PM Jarkko Sakkinen > wrote: > > > > Intel Software Guard eXtensions (SGX) is a set of CPU instructions that > > can be used by applications to set aside private regions of code and > > data. The code outside the enclave is disallowed to access the memory > > inside the enclave by the CPU access control. > > This is a very partial review. Thank you, appreciate it. > > +int sgx_encl_find(struct mm_struct *mm, unsigned long addr, > > + struct vm_area_struct **vma) > > +{ > > + struct vm_area_struct *result; > > + struct sgx_encl *encl; > > + > > + result = find_vma(mm, addr); > > + if (!result || result->vm_ops != &sgx_vm_ops || addr < result->vm_start) > > + return -EINVAL; > > + > > + encl = result->vm_private_data; > > + *vma = result; > > + > > + return encl ? 0 : -ENOENT; > > +} > > I realize that this function may go away entirely but, if you keep it: > what are the locking rules? What, if anything, prevents another > thread from destroying the enclave after sgx_encl_find() returns? The kref inside the enclave is used to manage this but this function directly does not prevent it (see for example sgx_encl_get). But yes, this function does not give any guarantees (should probably have a documentation stating this). > > +static int sgx_validate_secs(const struct sgx_secs *secs, > > + unsigned long ssaframesize) > > +{ > > ... > > > + if (secs->attributes & SGX_ATTR_MODE64BIT) { > > + if (secs->size > sgx_encl_size_max_64) > > + return -EINVAL; > > + } else { > > + /* On 64-bit architecture allow 32-bit encls only in > > + * the compatibility mode. > > + */ > > + if (!test_thread_flag(TIF_ADDR32)) > > + return -EINVAL; > > + if (secs->size > sgx_encl_size_max_32) > > + return -EINVAL; > > + } > > Why do we need the 32-bit-on-64-bit check? In general, anything that > checks per-task or per-mm flags like TIF_ADDR32 is IMO likely to be > problematic. You're allowing 64-bit enclaves in 32-bit tasks, so I'm > guessing you could just delete the check. I guess you are right. I can remove this. > > > + > > + if (!(secs->xfrm & XFEATURE_MASK_FP) || > > + !(secs->xfrm & XFEATURE_MASK_SSE) || > > + (((secs->xfrm >> XFEATURE_BNDREGS) & 1) != > > + ((secs->xfrm >> XFEATURE_BNDCSR) & 1)) || > > + (secs->xfrm & ~sgx_xfrm_mask)) > > + return -EINVAL; > > Do we need to check that the enclave doesn't use xfeatures that the > kernel doesn't know about? Or are they all safe by design in enclave > mode? Really good catch BTW. We don't check what kernel doesn't know about. I'm not sure what harm this would have as the enclave cannot have much effect to the outside world. Is there easy way to get similar mask of kernel supported features as sgx_xfrm_mask? The safe play would be to use such here as I don't have definitive answer to your second question. > > > +static int sgx_encl_pm_notifier(struct notifier_block *nb, > > + unsigned long action, void *data) > > +{ > > + struct sgx_encl *encl = container_of(nb, struct sgx_encl, pm_notifier); > > + > > + if (action != PM_SUSPEND_PREPARE && action != PM_HIBERNATION_PREPARE) > > + return NOTIFY_DONE; > > Hmm. There's an argument to made that omitting this would better > exercise the code that handles fully asynchronous loss of an enclave. > Also, I think you're unnecessarily killing enclaves when suspend is > attempted but fails. Are you proposing to not do anything at all to the enclaves? There was is a problem that it could lead to infinite #PF loop if we don't do it. > > > + > > +static int sgx_get_key_hash(const void *modulus, void *hash) > > +{ > > + struct crypto_shash *tfm; > > + int ret; > > + > > + tfm = crypto_alloc_shash("sha256", 0, CRYPTO_ALG_ASYNC); > > + if (IS_ERR(tfm)) > > + return PTR_ERR(tfm); > > + > > + ret = __sgx_get_key_hash(tfm, modulus, hash); > > + > > + crypto_free_shash(tfm); > > + return ret; > > +} > > + > > I'm so sorry you had to deal with this API. Once Zinc lands, you > could clean this up :) > > > > +static int sgx_encl_get(unsigned long addr, struct sgx_encl **encl) > > +{ > > + struct mm_struct *mm = current->mm; > > + struct vm_area_struct *vma; > > + int ret; > > + > > + if (addr & (PAGE_SIZE - 1)) > > + return -EINVAL; > > + > > + down_read(&mm->mmap_sem); > > + > > + ret = sgx_encl_find(mm, addr, &vma); > > + if (!ret) { > > + *encl = vma->vm_private_data; > > + > > + if ((*encl)->flags & SGX_ENCL_SUSPEND) > > + ret = SGX_POWER_LOST_ENCLAVE; > > + else > > + kref_get(&(*encl)->refcount); > > + } > > Hmm. This version has explicit refcounting. > > > +static int sgx_mmap(struct file *file, struct vm_area_struct *vma) > > +{ > > + vma->vm_ops = &sgx_vm_ops; > > + vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO | > > + VM_DONTCOPY; > > + > > + return 0; > > +} > > + > > +static unsigned long sgx_get_unmapped_area(struct file *file, > > + unsigned long addr, > > + unsigned long len, > > + unsigned long pgoff, > > + unsigned long flags) > > +{ > > + if (len < 2 * PAGE_SIZE || (len & (len - 1))) > > + return -EINVAL; > > + > > + if (len > sgx_encl_size_max_64) > > + return -EINVAL; > > + > > + if (len > sgx_encl_size_max_32 && test_thread_flag(TIF_ADDR32)) > > + return -EINVAL; > > Generally speaking, this type of check wants to be > in_compat_syscall(). But I'm not sure I understand why you need it at > all. I'll remove it. > > > +static void sgx_ipi_cb(void *info) > > +{ > > +} > > + > > +void sgx_flush_cpus(struct sgx_encl *encl) > > +{ > > + on_each_cpu_mask(mm_cpumask(encl->mm), sgx_ipi_cb, NULL, 1); > > +} > > Please add a comment explaining what this promises to do. Will do. /Jarkko