Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1101690ybi; Fri, 14 Jun 2019 08:39:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqw5LMCw3mSBrHpMaU51zGFVJb1L4z79ih3P2Uh36K19vmjUS8Vkb9s4tOcCfgZ3sb9JthT4 X-Received: by 2002:a17:90a:9905:: with SMTP id b5mr12041700pjp.70.1560526747385; Fri, 14 Jun 2019 08:39:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560526747; cv=none; d=google.com; s=arc-20160816; b=f2zlNhR46V3znk62y43ekcWA0fDuTqO2b/fmwxv/zaAyUB0KIg7FUbJz5LNRowcodN Vq5L2ppw9PbfAYXscfgtIac+gULNnVPTnaEPbeQmcGCZQa4KjCPOqni1H9VaK+TQpNbQ BTJBzxI8rr+dIQsiEXo9sZnrOuBn5tbMJtLPjggY/LqrY0hLES1Vhyr76AJD57cfP5kf qS7a7imjxqcjyDkvOs40pUfkemL9QAVFYUV89cYJ6HH6/s3QUEEjVmsZLn+FaGLEIoqf pTFSbM+MDRO+5j0AiTauvTr3QsBN500k1c+a5+BJeDtf6fPbZNBaFgrP8Xk333WjZ10O p5BQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=9GLhM7RVYfBV8UgJIDC9zbhAlZW9VEfNcfn85QQlmJ8=; b=npOILzW4knStYTfqeEs9xj97CbUDpgLEtIg0TqoOym5Vl4SSyWGf+lFWGRGmr4p74/ vRbo3/hkBzY6exUmYQ4aIf1pWGA4DmsgZXpw3OR7V4GSdwXGZpRHx3l7PkKr7BnLOmDd RwkVGzLYYN99hb/2vAifh9x+nY4Uctu1WHc2ABuq8tDfNqlMiDyvi50zebR5R8U79JCN +IElXELCR4TfBx2bmgfs8X83rgnIDl9hvNV6Qk/5KxhfZPHirhpwSrgSi+c/9gQOUZgM YXzYhYbRjln5nEQ0yUtpm8aknQQUBqbhF+N4NH+4u/YG4wPlcVAr4qQgMrqiib7z3gOq yRsQ== 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 c1si2482477pll.194.2019.06.14.08.38.51; Fri, 14 Jun 2019 08:39:07 -0700 (PDT) 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 S1726388AbfFNPil (ORCPT + 99 others); Fri, 14 Jun 2019 11:38:41 -0400 Received: from mga09.intel.com ([134.134.136.24]:20291 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725780AbfFNPil (ORCPT ); Fri, 14 Jun 2019 11:38:41 -0400 X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jun 2019 08:38:40 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com (HELO linux.intel.com) ([10.54.74.36]) by orsmga002.jf.intel.com with ESMTP; 14 Jun 2019 08:38:40 -0700 Date: Fri, 14 Jun 2019 08:38:40 -0700 From: Sean Christopherson To: Stephen Smalley Cc: Cedric Xing , linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sgx@vger.kernel.org, jarkko.sakkinen@linux.intel.com, luto@kernel.org, jmorris@namei.org, serge@hallyn.com, paul@paul-moore.com, eparis@parisplace.org, jethro@fortanix.com, dave.hansen@intel.com, tglx@linutronix.de, torvalds@linux-foundation.org, akpm@linux-foundation.org, nhorman@redhat.com, pmccallum@redhat.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, haitao.huang@intel.com, andriy.shevchenko@linux.intel.com, kai.svahn@intel.com, bp@alien8.de, josh@joshtriplett.org, kai.huang@intel.com, rientjes@google.com, william.c.roberts@intel.com, philip.b.tricca@intel.com Subject: Re: [RFC PATCH v1 2/3] LSM/x86/sgx: Implement SGX specific hooks in SELinux Message-ID: <20190614153840.GC12191@linux.intel.com> References: <20190611220243.GB3416@linux.intel.com> <8d99d8fb-a921-286a-8cf0-cd522e09b37c@tycho.nsa.gov> <20190614004600.GF18385@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190614004600.GF18385@linux.intel.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jun 13, 2019 at 05:46:00PM -0700, Sean Christopherson wrote: > On Thu, Jun 13, 2019 at 01:02:17PM -0400, Stephen Smalley wrote: > > On 6/11/19 6:02 PM, Sean Christopherson wrote: > > >On Tue, Jun 11, 2019 at 09:40:25AM -0400, Stephen Smalley wrote: > > >>I haven't looked at this code closely, but it feels like a lot of > > >>SGX-specific logic embedded into SELinux that will have to be repeated or > > >>reused for every security module. Does SGX not track this state itself? > > > > > >SGX does track equivalent state. > > > > > >There are three proposals on the table (I think): > > > > > > 1. Require userspace to explicitly specificy (maximal) enclave page > > > permissions at build time. The enclave page permissions are provided > > > to, and checked by, LSMs at enclave build time. > > > > > > Pros: Low-complexity kernel implementation, straightforward auditing > > > Cons: Sullies the SGX UAPI to some extent, may increase complexity of > > > SGX2 enclave loaders. > > > > > > 2. Pre-check LSM permissions and dynamically track mappings to enclave > > > pages, e.g. add an SGX mprotect() hook to restrict W->X and WX > > > based on the pre-checked permissions. > > > > > > Pros: Does not impact SGX UAPI, medium kernel complexity > > > Cons: Auditing is complex/weird, requires taking enclave-specific > > > lock during mprotect() to query/update tracking. > > > > > > 3. Implement LSM hooks in SGX to allow LSMs to track enclave regions > > > from cradle to grave, but otherwise defer everything to LSMs. > > > > > > Pros: Does not impact SGX UAPI, maximum flexibility, precise auditing > > > Cons: Most complex and "heaviest" kernel implementation of the three, > > > pushes more SGX details into LSMs. > > > > > >My RFC series[1] implements #1. My understanding is that Andy (Lutomirski) > > >prefers #2. Cedric's RFC series implements #3. > > > > > >Perhaps the easiest way to make forward progress is to rule out the > > >options we absolutely *don't* want by focusing on the potentially blocking > > >issue with each option: > > > > > > #1 - SGX UAPI funkiness > > > > > > #2 - Auditing complexity, potential enclave lock contention > > > > > > #3 - Pushing SGX details into LSMs and complexity of kernel implementation > > > > > > > > >[1] https://lkml.kernel.org/r/20190606021145.12604-1-sean.j.christopherson@intel.com > > > > Given the complexity tradeoff, what is the clear motivating example for why > > #1 isn't the obvious choice? That the enclave loader has no way of knowing a > > priori whether the enclave will require W->X or WX? But aren't we better > > off requiring enclaves to be explicitly marked as needing such so that we > > can make a more informed decision about whether to load them in the first > > place? > > Andy and/or Cedric, can you please weigh in with a concrete (and practical) > use case that will break if we go with #1? The auditing issues for #2/#3 > are complex to say the least... Follow-up question, is #1 any more palatable if SELinux adds SGX specific permissions and ties them to the process (instead of the vma or sigstruct)? Something like this for SELinux, where the absolute worst case scenario is that SGX2 enclave loaders need SGXEXECMEM. Graphene would need SGXEXECUNMR and probably SGXEXECANON. static inline int sgx_has_perm(u32 sid, u32 requested) { return avc_has_perm(&selinux_state, sid, sid, SECCLASS_PROCESS2, requested, NULL); } static int selinux_enclave_load(struct vm_area_struct *vma, unsigned long prot, bool measured) { const struct cred *cred = current_cred(); u32 sid = cred_sid(cred); int ret; /* SGX is supported only in 64-bit kernels. */ WARN_ON_ONCE(!default_noexec); /* Only executable enclave pages are restricted in any way. */ if (!(prot & PROT_EXEC)) return 0; /* * Private mappings to enclave pages are impossible, ergo we don't * differentiate between W->X and WX, either case requires EXECMEM. */ if (prot & PROT_WRITE) { ret = sgx_has_perm(sid, PROCESS2__SGXEXECMEM); if (ret) goto out; } if (!measured) { ret = sgx_has_perm(sid, PROCESS2__SGXEXECUNMR); if (ret) goto out; } if (!vma->vm_file || !IS_PRIVATE(file_inode(vma->vm_file)) || vma->anon_vma) { /* * Loading enclave code from an anonymous mapping or from a * modified private file mapping. */ ret = sgx_has_perm(sid, PROCESS2__SGXEXECANON); if (ret) goto out; } else { /* Loading from a shared or unmodified private file mapping. */ ret = sgx_has_perm(sid, PROCESS2__SGXEXECFILE); if (ret) goto out; /* The source file must be executable in this case. */ ret = file_has_perm(cred, vma->vm_file, FILE__EXECUTE); if (ret) goto out; } out: return ret; } Given that AppArmor generally only cares about accessing files, its enclave_load() implementation would be something like: static int apparmor_enclave_load(struct vm_area_struct *vma, unsigned long prot, bool measured) { if (!(prot & PROT_EXEC)) return 0; return common_file_perm(OP_ENCL_LOAD, vma->vm_file, AA_EXEC_MMAP); }