SGX vs LSM (Re: [PATCH v20 00/28] Intel SGX1 support)

Andy Lutomirski luto at kernel.org
Thu May 30 14:31:14 UTC 2019


Hi all-

After an offline discussion with Sean yesterday, here are some updates
to the user API parts of my proposal.

Unfortunately, Sean convinced me that MAXPERM doesn't work the way I
described it because, for SGX2, the enclave loader won't know at load
time whether a given EAUG-ed page will ever be executed.  So here's an
update.

First, here are the requrements as I see them, where EXECUTE, EXECMOD,
and EXECMEM could be substituted with other rules at the LSM's
discretion:

 - You can create a WX or RWX mapping if and only if you have EXECMEM.

 - To create an X mapping of an enclave page that has ever been W, you
need EXECMOD.

 - To create an X mapping of an enclave page that came from EADD, you
need EXECUTE on the source file.  Optionally, we could also permit
this if you have EXECMOD.

And I have two design proposals.  One is static and one is dynamic.
To implement either one, we will probably need a new .may_mprotect vm
operation, and that operation can call an LSM hook.  Or we can give
LSMs a way to detect that a given vm_area_struct is an enclave.  As I
see it, this is an implementation detail that is certainly solveable.


Static proposal:


EADD takes an execute_intent flag.  It calls a new hook:

  int security_enclave_load(struct vm_area_struct *source, bool execute_intent);

This hook will fail if execute_intent==true and the caller has neither
EXECUTE, EXECMOD, nor EXECMEM.

EAUG sets execute_intent = false.

EINIT takes a sigstruct pointer.  SGX can (when initially upstreamed
or later on once there's demand) call a new hook:

  security_enclave_init(struct sigstruct *sigstruct, struct
vm_area_struct *source);

mmap() and mprotect() will require EXECMEM to create WX or RWX
mappings.  They will require EXECMOD to create RX or X mappings of an
execute_intent==false page.  They require no permissions in the other
cases.


Dynamic proposal:


EADD does not take any special flags.  It does something like this internally:

  bool execute_intent = true;
  int security_enclave_load(struct vm_area_struct *source, bool
*execute_intent);

The implementation of security_enclave_load() may set *execute_intent to false.
The driver records execute_intent after the LSM is done.

mmap() and mprotect() will require EXECMEM to create WX or RWX
mappings.  They will require EXECMOD to create RX or X mappings of an
execute_intent==false page.  They require no permissions in the other
cases.



A benefit of the static proposal is that audit failures due to a lack
of EXECUTE permission are easy to implement and to understand in the
lods.  With the dynamic model, we can only really audit the lack of
EXECMOD or EXECMEM.  A benefit of the dynamic model is that we hide
what is arguably a decently large wart from the API.



More information about the Linux-security-module-archive mailing list