From d0331bd39747e7410e9413a00299b7584a529c2f Mon Sep 17 00:00:00 2001 From: "Hui, Chunyang" Date: Thu, 11 Mar 2021 05:57:43 +0000 Subject: [PATCH] Add detection for FSGSBASE enablement in PAL --- src/pal/src/pal_api.c | 9 +++++ src/pal/src/pal_check_fsgsbase.c | 63 ++++++++++++++++++++++++++++++++ src/pal/src/pal_check_fsgsbase.h | 8 ++++ 3 files changed, 80 insertions(+) create mode 100644 src/pal/src/pal_check_fsgsbase.c create mode 100644 src/pal/src/pal_check_fsgsbase.h diff --git a/src/pal/src/pal_api.c b/src/pal/src/pal_api.c index 9ff82b8d..7eedfce8 100644 --- a/src/pal/src/pal_api.c +++ b/src/pal/src/pal_api.c @@ -7,6 +7,7 @@ #include "pal_sig_handler.h" #include "pal_syscall.h" #include "pal_thread_counter.h" +#include "pal_check_fsgsbase.h" #include "errno2str.h" #include @@ -77,6 +78,14 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) { return -1; } +// Check only for SGX hardware mode +#ifdef SGX_MODE_HW + if (check_fsgsbase_enablement() != 0) { + PAL_ERROR("FSGSBASE enablement check failed."); + return -1; + } +#endif + sgx_enclave_id_t eid = pal_get_enclave_id(); if (eid != SGX_INVALID_ENCLAVE_ID) { PAL_ERROR("Enclave has been initialized."); diff --git a/src/pal/src/pal_check_fsgsbase.c b/src/pal/src/pal_check_fsgsbase.c new file mode 100644 index 00000000..3b9312da --- /dev/null +++ b/src/pal/src/pal_check_fsgsbase.c @@ -0,0 +1,63 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pal_log.h" +#include "pal_check_fsgsbase.h" + +#define RC 0xffff +static jmp_buf env_buf; + +static void handle_sigill(int num) { + assert(num == SIGILL); + + longjmp(env_buf, RC); +} + +int check_fsgsbase_enablement(void) { + int gs_read_data = 0; + int gs_write_data = 0x0f; + int __seg_gs *offset_ptr = 0; // offset relative to GS. support since gcc-6 + + sighandler_t handler_orig = signal(SIGILL, handle_sigill); + if (handler_orig == SIG_ERR) { + PAL_ERROR("registering signal handler failed, errno = %d", errno); + return errno; + } + + int ret = setjmp(env_buf); + if (ret == RC) { + // return from SIGILL handler + PAL_ERROR("\tSIGILL Caught !"); + return -1; + } + if (ret != 0) { + PAL_ERROR("setjmp failed"); + return -1; + } + + // Check if kernel supports FSGSBASE + asm("rdgsbase %0" :: "r" (&gs_read_data)); + asm("wrgsbase %0" :: "r" (&gs_write_data)); + + if (*offset_ptr != 0x0f) { + PAL_ERROR("GS register data not match\n"); + return -1; + }; + + // Restore the GS register and original signal handler + asm("wrgsbase %0" :: "r" (&gs_read_data)); + handler_orig = signal(SIGILL, handler_orig); + if (handler_orig == SIG_ERR) { + PAL_ERROR("restoring default signal handler failed, errno = %d", errno); + return errno; + } + + return 0; +} diff --git a/src/pal/src/pal_check_fsgsbase.h b/src/pal/src/pal_check_fsgsbase.h new file mode 100644 index 00000000..3caa757d --- /dev/null +++ b/src/pal/src/pal_check_fsgsbase.h @@ -0,0 +1,8 @@ +#ifndef __PAL_CHECK_FSGSBASE_H__ +#define __PAL_CHECK_FSGSBASE_H__ + +// Check if FSGSBASE instructions are supported. +// Return 0 if the check pass. +int check_fsgsbase_enablement(void); + +#endif