Add detection for FSGSBASE enablement in PAL
This commit is contained in:
parent
d81511ec8c
commit
d0331bd397
@ -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.");
|
||||
|
63
src/pal/src/pal_check_fsgsbase.c
Normal file
63
src/pal/src/pal_check_fsgsbase.c
Normal file
@ -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;
|
||||
}
|
8
src/pal/src/pal_check_fsgsbase.h
Normal file
8
src/pal/src/pal_check_fsgsbase.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user