Message ID | 20200716135303.276442-4-jarkko.sakkinen@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Intel SGX foundations | expand |
On Thursday, 2020-07-16 at 16:52:42 +03, Jarkko Sakkinen wrote: > From: Sean Christopherson <sean.j.christopherson@intel.com> > > Include SGX bit to the PF error codes and throw SIGSEGV with PF_SGX when > a #PF with SGX set happens. > > CPU throws a #PF with the SGX set in the event of Enclave Page Cache Map > (EPCM) conflict. The EPCM is a CPU-internal table, which describes the > properties for a enclave page. Enclaves are measured and signed software > entities, which SGX hosts. [1] > > Although the primary purpose of the EPCM conflict checks is to prevent > malicious accesses to an enclave, an illegit access can happen also for > legit reasons. > > All SGX reserved memory, including EPCM is encrypted with a transient key > that does not survive from the power transition. Throwing a SIGSEGV allows > user space software to react when this happens (e.g. recreate the enclave, > which was invalidated). > > [1] Intel SDM: 36.5.1 Enclave Page Cache Map (EPCM) > > Acked-by: Jethro Beekman <jethro@fortanix.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> > --- > arch/x86/include/asm/traps.h | 14 ++++++++------ > arch/x86/mm/fault.c | 13 +++++++++++++ > 2 files changed, 21 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h > index 714b1a30e7b0..4446f95ad997 100644 > --- a/arch/x86/include/asm/traps.h > +++ b/arch/x86/include/asm/traps.h > @@ -44,12 +44,13 @@ void __noreturn handle_stack_overflow(const char *message, > /* > * Page fault error code bits: > * > - * bit 0 == 0: no page found 1: protection fault > - * bit 1 == 0: read access 1: write access > - * bit 2 == 0: kernel-mode access 1: user-mode access > - * bit 3 == 1: use of reserved bit detected > - * bit 4 == 1: fault was an instruction fetch > - * bit 5 == 1: protection keys block access > + * bit 0 == 0: no page found 1: protection fault > + * bit 1 == 0: read access 1: write access > + * bit 2 == 0: kernel-mode access 1: user-mode access > + * bit 3 == 1: use of reserved bit detected > + * bit 4 == 1: fault was an instruction fetch > + * bit 5 == 1: protection keys block access > + * bit 15 == 1: inside SGX enclave > */ > enum x86_pf_error_code { > X86_PF_PROT = 1 << 0, > @@ -58,5 +59,6 @@ enum x86_pf_error_code { > X86_PF_RSVD = 1 << 3, > X86_PF_INSTR = 1 << 4, > X86_PF_PK = 1 << 5, > + X86_PF_SGX = 1 << 15, > }; > #endif /* _ASM_X86_TRAPS_H */ > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index 1ead568c0101..1db6fbd7af8e 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -1055,6 +1055,19 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) > if (error_code & X86_PF_PK) > return 1; > > + /* > + * Access is blocked by the Enclave Page Cache Map (EPCM), i.e. the > + * access is allowed by the PTE but not the EPCM. This usually happens > + * when the EPCM is yanked out from under us, e.g. by hardware after a > + * suspend/resume cycle. In any case, software, i.e. the kernel, can't > + * fix the source of the fault as the EPCM can't be directly modified by > + * software. Handle the fault as an access error in order to signal > + * userspace so that userspace can rebuild their enclave(s), even though > + * userspace may not have actually violated access permissions. > + */ > + if (unlikely(error_code & X86_PF_SGX)) > + return 1; > + > /* > * Make sure to check the VMA so that we do not perform > * faults just to hit a X86_PF_PK as soon as we fill in a > -- > 2.25.1
On Thu, Jul 16, 2020 at 04:52:42PM +0300, Jarkko Sakkinen wrote: > From: Sean Christopherson <sean.j.christopherson@intel.com> > > Include SGX bit to the PF error codes and throw SIGSEGV with PF_SGX when > a #PF with SGX set happens. > > CPU throws a #PF with the SGX set in the event of Enclave Page Cache Map > (EPCM) conflict. The EPCM is a CPU-internal table, which describes the > properties for a enclave page. Enclaves are measured and signed software > entities, which SGX hosts. [1] > > Although the primary purpose of the EPCM conflict checks is to prevent > malicious accesses to an enclave, an illegit access can happen also for > legit reasons. > > All SGX reserved memory, including EPCM is encrypted with a transient key > that does not survive from the power transition. Throwing a SIGSEGV allows > user space software to react when this happens (e.g. recreate the enclave, > which was invalidated). > > [1] Intel SDM: 36.5.1 Enclave Page Cache Map (EPCM) > > Acked-by: Jethro Beekman <jethro@fortanix.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > --- > arch/x86/include/asm/traps.h | 14 ++++++++------ > arch/x86/mm/fault.c | 13 +++++++++++++ > 2 files changed, 21 insertions(+), 6 deletions(-) Reviewed-by: Borislav Petkov <bp@suse.de>
On Thu, Aug 20, 2020 at 05:31:14PM +0200, Borislav Petkov wrote: > On Thu, Jul 16, 2020 at 04:52:42PM +0300, Jarkko Sakkinen wrote: > > From: Sean Christopherson <sean.j.christopherson@intel.com> > > > > Include SGX bit to the PF error codes and throw SIGSEGV with PF_SGX when > > a #PF with SGX set happens. > > > > CPU throws a #PF with the SGX set in the event of Enclave Page Cache Map > > (EPCM) conflict. The EPCM is a CPU-internal table, which describes the > > properties for a enclave page. Enclaves are measured and signed software > > entities, which SGX hosts. [1] > > > > Although the primary purpose of the EPCM conflict checks is to prevent > > malicious accesses to an enclave, an illegit access can happen also for > > legit reasons. > > > > All SGX reserved memory, including EPCM is encrypted with a transient key > > that does not survive from the power transition. Throwing a SIGSEGV allows > > user space software to react when this happens (e.g. recreate the enclave, > > which was invalidated). > > > > [1] Intel SDM: 36.5.1 Enclave Page Cache Map (EPCM) > > > > Acked-by: Jethro Beekman <jethro@fortanix.com> > > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > > --- > > arch/x86/include/asm/traps.h | 14 ++++++++------ > > arch/x86/mm/fault.c | 13 +++++++++++++ > > 2 files changed, 21 insertions(+), 6 deletions(-) > > Reviewed-by: Borislav Petkov <bp@suse.de> Thank you. Appended to the commit. > > -- > Regards/Gruss, > Boris. > > https://people.kernel.org/tglx/notes-about-netiquette /Jarkko
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 714b1a30e7b0..4446f95ad997 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -44,12 +44,13 @@ void __noreturn handle_stack_overflow(const char *message, /* * Page fault error code bits: * - * bit 0 == 0: no page found 1: protection fault - * bit 1 == 0: read access 1: write access - * bit 2 == 0: kernel-mode access 1: user-mode access - * bit 3 == 1: use of reserved bit detected - * bit 4 == 1: fault was an instruction fetch - * bit 5 == 1: protection keys block access + * bit 0 == 0: no page found 1: protection fault + * bit 1 == 0: read access 1: write access + * bit 2 == 0: kernel-mode access 1: user-mode access + * bit 3 == 1: use of reserved bit detected + * bit 4 == 1: fault was an instruction fetch + * bit 5 == 1: protection keys block access + * bit 15 == 1: inside SGX enclave */ enum x86_pf_error_code { X86_PF_PROT = 1 << 0, @@ -58,5 +59,6 @@ enum x86_pf_error_code { X86_PF_RSVD = 1 << 3, X86_PF_INSTR = 1 << 4, X86_PF_PK = 1 << 5, + X86_PF_SGX = 1 << 15, }; #endif /* _ASM_X86_TRAPS_H */ diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 1ead568c0101..1db6fbd7af8e 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1055,6 +1055,19 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) if (error_code & X86_PF_PK) return 1; + /* + * Access is blocked by the Enclave Page Cache Map (EPCM), i.e. the + * access is allowed by the PTE but not the EPCM. This usually happens + * when the EPCM is yanked out from under us, e.g. by hardware after a + * suspend/resume cycle. In any case, software, i.e. the kernel, can't + * fix the source of the fault as the EPCM can't be directly modified by + * software. Handle the fault as an access error in order to signal + * userspace so that userspace can rebuild their enclave(s), even though + * userspace may not have actually violated access permissions. + */ + if (unlikely(error_code & X86_PF_SGX)) + return 1; + /* * Make sure to check the VMA so that we do not perform * faults just to hit a X86_PF_PK as soon as we fill in a