Add detection for FSGSBASE enablement in PAL

This commit is contained in:
Hui, Chunyang 2021-03-11 05:57:43 +00:00 committed by Zongmin.Gu
parent d81511ec8c
commit d0331bd397
3 changed files with 80 additions and 0 deletions

@ -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 <linux/limits.h>
@ -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.");

@ -0,0 +1,63 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <signal.h>
#include <assert.h>
#include <string.h>
#include <ucontext.h>
#include <setjmp.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

@ -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