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_sig_handler.h"
|
||||||
#include "pal_syscall.h"
|
#include "pal_syscall.h"
|
||||||
#include "pal_thread_counter.h"
|
#include "pal_thread_counter.h"
|
||||||
|
#include "pal_check_fsgsbase.h"
|
||||||
#include "errno2str.h"
|
#include "errno2str.h"
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
|
||||||
@ -77,6 +78,14 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) {
|
|||||||
return -1;
|
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();
|
sgx_enclave_id_t eid = pal_get_enclave_id();
|
||||||
if (eid != SGX_INVALID_ENCLAVE_ID) {
|
if (eid != SGX_INVALID_ENCLAVE_ID) {
|
||||||
PAL_ERROR("Enclave has been initialized.");
|
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