All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: "Xing, Cedric" <cedric.xing@intel.com>
Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	James Morris <jmorris@namei.org>,
	"Serge E . Hallyn" <serge@hallyn.com>,
	LSM List <linux-security-module@vger.kernel.org>,
	Paul Moore <paul@paul-moore.com>,
	Eric Paris <eparis@parisplace.org>,
	"selinux@vger.kernel.org" <selinux@vger.kernel.org>,
	Jethro Beekman <jethro@fortanix.com>,
	"Hansen, Dave" <dave.hansen@intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>, X86 ML <x86@kernel.org>,
	"linux-sgx@vger.kernel.org" <linux-sgx@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	"nhorman@redhat.com" <nhorman@redhat.com>,
	"npmccallum@redhat.com" <npmccallum@redhat.com>,
	"Ayoun, Serge" <serge.ayoun@intel.com>,
	"Katz-zamir, Shay" <shay.katz-zamir@intel.com>,
	"Huang, Haitao" <haitao.huang@intel.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	"Svahn, Kai" <kai.svahn@intel.com>,
	Borislav Petkov <bp@alien8.de>,
	Josh Triplett <josh@joshtriplett.org>,
	"Huang, Kai" <kai.huang@intel.com>,
	David Rientjes <rientjes@google.com>,
	"Roberts, William C" <william.c.roberts@intel.com>,
	"Tricca, Philip B" <philip.b.tricca@intel.com>
Subject: Re: [RFC PATCH 0/9] security: x86/sgx: SGX vs. LSM
Date: Mon, 3 Jun 2019 10:15:49 -0700	[thread overview]
Message-ID: <20190603171549.GE13384@linux.intel.com> (raw)
In-Reply-To: <960B34DE67B9E140824F1DCDEC400C0F654EC5FD@ORSMSX116.amr.corp.intel.com>

On Sun, Jun 02, 2019 at 12:29:35AM -0700, Xing, Cedric wrote:
> Hi Sean,
> 
> > From: Christopherson, Sean J
> > Sent: Friday, May 31, 2019 4:32 PM
> > 
> > This series is the result of a rather absurd amount of discussion over how to get SGX to play
> > nice with LSM policies, without having to resort to evil shenanigans or put undue burden on
> > userspace.  The discussion definitely wandered into completely insane territory at times, but
> > I think/hope we ended up with something reasonable.
> > 
> > The basic gist of the approach is to require userspace to declare what protections are
> > maximally allowed for any given page, e.g. add a flags field for loading enclave pages that
> > takes ALLOW_{READ,WRITE,EXEC}.  LSMs can then adjust the allowed protections, e.g. clear
> > ALLOW_EXEC to prevent ever mapping the page with PROT_EXEC.  SGX enforces the allowed perms
> > via a new mprotect() vm_ops hook, e.g. like regular mprotect() uses MAY_{READ,WRITE,EXEC}.
> > 
> > ALLOW_EXEC is used to deny hings like loading an enclave from a noexec file system or from a
> > file without EXECUTE permissions, e.g. without the ALLOW_EXEC concept, on SGX2 hardware
> > (regardless of kernel support) userspace could EADD from a noexec file using read-only
> > permissions, and later use mprotect() and ENCLU[EMODPE] to gain execute permissions.
> > 
> > ALLOW_WRITE is used in conjuction with ALLOW_EXEC to enforce SELinux's EXECMOD (or EXECMEM).
> > 
> > This is very much an RFC series.  It's only compile tested, likely has obvious bugs, the
> > SELinux patch could be completely harebrained, etc...
> > My goal at this point is to get feedback at a macro level, e.g. is the core concept
> > viable/acceptable, are there objection to hooking mprotect(), etc...
> > 
> > Andy and Cedric, hopefully this aligns with your general expectations based on our last
> > discussion.
> 
> I couldn't understand the real intentions of ALLOW_* flags until I saw them
> in code. I have to say C is more expressive than English in that regard :)
> 
> Generally I agree with your direction but think ALLOW_* flags are completely
> internal to LSM because they can be both produced and consumed inside an LSM
> module. So spilling them into SGX driver and also user mode code makes the
> solution ugly and in some cases impractical because not every enclave host
> process has a priori knowledge on whether or not an enclave page would be
> EMODPE'd at runtime.

In this case, the host process should tag *all* pages it *might* convert
to executable as ALLOW_EXEC.  LSMs can (and should/will) be written in
such a way that denying ALLOW_EXEC is fatal to the enclave if and only if
the enclave actually attempts mprotect(PROT_EXEC).

Take the SELinux path for example.  The only scenario in which PROT_WRITE
is cleared from @allowed_prot is if the page *starts* with PROT_EXEC.
If PROT_EXEC is denied on a page that starts RW, e.g. an EAUG'd page,
then PROT_EXEC will be cleared from @allowed_prot.

As Stephen pointed out, auditing the denials on @allowed_prot means the
log will contain false positives of a sort.  But this is more of a noise
issue than true false positives.  E.g. there are three possible outcomes
for the enclave.

  - The enclave does not do EMODPE[PROT_EXEC] in any scenario, ever.
    Requesting ALLOW_EXEC is either a straightforward a userspace bug or
    a poorly written generic enclave loader.

  - The enclave conditionally performs EMODPE[PROT_EXEC].  In this case
    the denial is a true false positive.
  
  - The enclave does EMODPE[PROT_EXEC] and its host userspace then fails
    on mprotect(PROT_EXEC), i.e. the LSM denial is working as intended.
    The audit log will be noisy, but viewed as a whole the denials aren't
    false positives.

The potential for noisy audit logs and/or false positives is unfortunate,
but it's (by far) the lesser of many evils.

> Theoretically speaking, what you really need is a per page flag (let's name
> it WRITTEN?) indicating whether a page has ever been written to (or more
> precisely, granted PROT_WRITE), which will be used to decide whether to grant
> PROT_EXEC when requested in future. Given the fact that all mprotect() goes
> through LSM and mmap() is limited to PROT_NONE, it's easy for LSM to capture
> that flag by itself instead of asking user mode code to provide it.
>
> That said, here is the summary of what I think is a better approach.
> * In hook security_file_alloc(), if @file is an enclave, allocate some data
>   structure to store for every page, the WRITTEN flag as described above.
>   WRITTEN is cleared initially for all pages.

This would effectively require *every* LSM to duplicate the SGX driver's
functionality, e.g. track per-page metadata, implement locking to prevent
races between multiple mm structs, etc...

>   Open: Given a file of type struct file *, how to tell if it is an enclave (i.e. /dev/sgx/enclave)?
> * In hook security_mmap_file(), if @file is an enclave, make sure @prot can
>   only be PROT_NONE. This is to force all protection changes to go through
>   security_file_mprotect().
> * In the newly introduced hook security_enclave_load(), set WRITTEN for pages
>   that are requested PROT_WRITE.

How would an LSM associate a page with a specific enclave?  vma->vm_file
will point always point at /dev/sgx/enclave.  vma->vm_mm is useless
because we're allowing multiple processes to map a single enclave, not to
mention that by mm would require holding a reference to the mm.

> * In hook security_file_mprotect(), if @vma->vm_file is an enclave, look up
>   and use WRITTEN flags for all pages within @vma, along with other global
>   flags (e.g. PROCESS__EXECMEM/FILE__EXECMOD in the case of SELinux) to decide
>   on allowing/rejecting @prot.

vma->vm_file will always be /dev/sgx/enclave at this point, which means
LSMs don't have the necessary anchor back to the source file, e.g. to
enforce FILE__EXECUTE.  The noexec file system case is also unaddressed.

> * In hook security_file_free(), if @file is an  enclave, free storage
>   allocated for WRITTEN flags.

  reply	other threads:[~2019-06-03 17:15 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-31 23:31 [RFC PATCH 0/9] security: x86/sgx: SGX vs. LSM Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 1/9] x86/sgx: Remove unused local variable in sgx_encl_release() Sean Christopherson
2019-06-04 11:41   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 2/9] x86/sgx: Do not naturally align MAP_FIXED address Sean Christopherson
2019-06-04 11:49   ` Jarkko Sakkinen
2019-06-04 20:16     ` Andy Lutomirski
2019-06-04 22:10       ` Xing, Cedric
2019-06-05 14:08         ` Sean Christopherson
2019-06-05 15:17         ` Jarkko Sakkinen
2019-06-05 20:14           ` Andy Lutomirski
2019-06-06 15:37             ` Jarkko Sakkinen
2019-06-13 13:48               ` Jarkko Sakkinen
2019-06-13 16:47                 ` Xing, Cedric
2019-06-13 17:14                   ` Sean Christopherson
2019-06-14 15:18                     ` Jarkko Sakkinen
2019-06-05 15:15       ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 3/9] x86/sgx: Allow userspace to add multiple pages in single ioctl() Sean Christopherson
2019-06-03  6:26   ` Xing, Cedric
2019-06-03 20:08     ` Sean Christopherson
2019-06-03 20:39       ` Sean Christopherson
2019-06-03 23:45         ` Xing, Cedric
2019-06-04  0:54           ` Sean Christopherson
2019-06-04 20:18         ` Andy Lutomirski
2019-06-04 22:02           ` Xing, Cedric
2019-06-03 20:14   ` Dave Hansen
2019-06-03 20:37     ` Sean Christopherson
2019-06-03 20:39       ` Dave Hansen
2019-06-03 23:48       ` Xing, Cedric
2019-06-04  0:55         ` Sean Christopherson
2019-06-04 11:55   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 4/9] mm: Introduce vm_ops->mprotect() Sean Christopherson
2019-06-03  6:27   ` Xing, Cedric
2019-06-04 12:24   ` Jarkko Sakkinen
2019-06-04 14:51   ` Andy Lutomirski
2019-05-31 23:31 ` [RFC PATCH 5/9] x86/sgx: Restrict mapping without an enclave page to PROT_NONE Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-04 15:32   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 6/9] x86/sgx: Require userspace to provide allowed prots to ADD_PAGES Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-04 16:23   ` Jarkko Sakkinen
2019-06-04 16:45     ` Sean Christopherson
2019-06-05 15:06       ` Jarkko Sakkinen
2019-06-04 20:23   ` Andy Lutomirski
2019-06-05 11:10   ` Ayoun, Serge
2019-06-05 23:58     ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 7/9] x86/sgx: Enforce noexec filesystem restriction for enclaves Sean Christopherson
2019-06-03  6:29   ` Xing, Cedric
2019-06-04 20:26     ` Andy Lutomirski
2019-06-04 16:25   ` Jarkko Sakkinen
2019-06-04 20:25     ` Andy Lutomirski
2019-06-04 20:34       ` Sean Christopherson
2019-06-04 21:54       ` Xing, Cedric
2019-06-05 15:10       ` Jarkko Sakkinen
2019-06-06  1:01         ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 8/9] LSM: x86/sgx: Introduce ->enclave_load() hook for Intel SGX Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-03 14:19   ` Stephen Smalley
2019-06-03 14:42     ` Sean Christopherson
2019-06-03 18:38       ` Stephen Smalley
2019-06-03 18:45         ` Dave Hansen
2019-06-04 20:29   ` Andy Lutomirski
2019-06-04 20:36     ` Sean Christopherson
2019-06-04 21:43       ` Xing, Cedric
2019-06-06  2:04         ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 9/9] security/selinux: Add enclave_load() implementation Sean Christopherson
2019-06-03 15:01   ` Stephen Smalley
2019-06-03 15:50     ` Sean Christopherson
2019-06-02  7:29 ` [RFC PATCH 0/9] security: x86/sgx: SGX vs. LSM Xing, Cedric
2019-06-03 17:15   ` Sean Christopherson [this message]
2019-06-03 18:30     ` Xing, Cedric
2019-06-04  1:36       ` Sean Christopherson
2019-06-04 15:33       ` Stephen Smalley
2019-06-04 16:30         ` Sean Christopherson
2019-06-04 21:38         ` Xing, Cedric
2019-06-03 17:47   ` Stephen Smalley
2019-06-03 18:02     ` Xing, Cedric
2019-06-04 11:15 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190603171549.GE13384@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=cedric.xing@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=eparis@parisplace.org \
    --cc=haitao.huang@intel.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jethro@fortanix.com \
    --cc=jmorris@namei.org \
    --cc=josh@joshtriplett.org \
    --cc=kai.huang@intel.com \
    --cc=kai.svahn@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-sgx@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=nhorman@redhat.com \
    --cc=npmccallum@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=philip.b.tricca@intel.com \
    --cc=rientjes@google.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@vger.kernel.org \
    --cc=serge.ayoun@intel.com \
    --cc=serge@hallyn.com \
    --cc=shay.katz-zamir@intel.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=william.c.roberts@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.