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