Skip to content

Commit 3be7be4

Browse files
authored
Fix data races around g_enclave_state (#889)
Before this commit, the memory access within `do_init_enclave` setting `g_enclave_state` to `ENCLAVE_INIT_DONE` was entirely unsynchronized. This could cause the compiler to reorder this access, performing it earlier than actually written. This would effectively unlock the memory being initialized for use within other threads before the initialization is finished. The issue isn't entirely theoretical, as such an optimization could for example allow to make one of the calls to `memset_s` a tailcall. The only thing preventing this is the difficulty of proving that the memset doesn't alias `g_enclave_state`. One way to fix this would be to access `g_enclave_state` with C11 atomics of ordering `acq_rel` or stronger. However, the freestanding environment of the SDK doesn't support C11 atomics. Thus we use the existing assembly wrappers, which are sufficient as achieving `acq_rel` semantics in x86 assembly doesn't require any special instructions. To make it less likely that a similar flaw is reintroduced, we remove the `extern` declaration of `g_enclave_state` from the header files. Signed-off-by: Maja Kądziołka <maya@invisiblethingslab.com>
1 parent ec0a8ed commit 3be7be4

File tree

4 files changed

+13
-10
lines changed

4 files changed

+13
-10
lines changed

common/inc/internal/global_data.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ typedef struct _global_data_t
7878
extern "C" {
7979
#endif
8080
extern SE_DECLSPEC_EXPORT global_data_t const volatile g_global_data;
81-
extern uint32_t g_enclave_state;
8281
extern sdk_version_t g_sdk_version;
8382
extern int EDMM_supported;
8483
extern uint8_t __ImageBase;

sdk/trts/init_enclave.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ uint64_t g_enclave_size __attribute__((section(RELRO_SECTION_NAME))) = 0;
6262

6363
const volatile global_data_t g_global_data __attribute__((section(".niprod"))) = {VERSION_UINT, 1, 2, 3, 4, 5, 6, 0, 0, 0,
6464
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, {{{0, 0, 0, 0, 0, 0, 0}}}, 0, 0, 0};
65+
66+
// Make sure to access this with atomics or the {get,set}_enclave_state assembly wrappers.
6567
uint32_t g_enclave_state __attribute__((section(".nipd"))) = ENCLAVE_INIT_NOT_STARTED;
68+
6669
uint32_t g_cpu_core_num __attribute__((section(RELRO_SECTION_NAME))) = 0;
6770

6871
extern "C" {
@@ -267,7 +270,7 @@ sgx_status_t do_init_enclave(void *ms, void *tcs)
267270
}
268271
#endif
269272
270-
g_enclave_state = ENCLAVE_INIT_DONE;
273+
set_enclave_state(ENCLAVE_INIT_DONE);
271274
272275
#ifndef SE_SIM
273276
// EDMM initialization makes ocalls which requires ENCLAVE_INIT_DONE being set

sdk/trts/init_optimized_lib.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "sgx_trts.h"
3737
#include "sgx_attributes.h"
3838
#include "global_data.h"
39+
#include "trts_internal.h"
3940

4041
extern "C" int sgx_init_string_lib(uint64_t cpu_feature_indicator);
4142
extern "C" sgx_status_t sgx_init_crypto_lib(uint64_t cpu_feature_indicator, uint32_t *cpuinfo_table);
@@ -94,7 +95,7 @@ static int set_global_feature_indicator(uint64_t feature_bit_array, uint64_t xfr
9495

9596
extern "C" int init_optimized_libs(const uint64_t feature_bit_array, uint32_t *cpuinfo_table, uint64_t xfrm)
9697
{
97-
if (g_enclave_state != ENCLAVE_INIT_IN_PROGRESS)
98+
if (get_enclave_state() != ENCLAVE_INIT_IN_PROGRESS)
9899
{
99100
return -1;
100101
}

sdk/trts/trts_veh.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
351351
sp_u = ssa_gpr->REG(sp_u);
352352
if (!sgx_is_outside_enclave((void *)sp_u, sizeof(sp_u)))
353353
{
354-
g_enclave_state = ENCLAVE_CRASHED;
354+
set_enclave_state(ENCLAVE_CRASHED);
355355
return SGX_ERROR_STACK_OVERRUN;
356356
}
357357

@@ -360,13 +360,13 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
360360
sp = ssa_gpr->REG(sp);
361361
if (sp_u == sp)
362362
{
363-
g_enclave_state = ENCLAVE_CRASHED;
363+
set_enclave_state(ENCLAVE_CRASHED);
364364
return SGX_ERROR_STACK_OVERRUN;
365365
}
366366

367367
if(!is_stack_addr((void*)sp, 0)) // check stack overrun only, alignment will be checked after exception handled
368368
{
369-
g_enclave_state = ENCLAVE_CRASHED;
369+
set_enclave_state(ENCLAVE_CRASHED);
370370
return SGX_ERROR_STACK_OVERRUN;
371371
}
372372

@@ -383,7 +383,7 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
383383
// check the decreased sp to make sure it is in the trusted stack range
384384
if(!is_stack_addr((void *)sp, size))
385385
{
386-
g_enclave_state = ENCLAVE_CRASHED;
386+
set_enclave_state(ENCLAVE_CRASHED);
387387
return SGX_ERROR_STACK_OVERRUN;
388388
}
389389

@@ -393,7 +393,7 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
393393
sp -= size;
394394
if(!is_stack_addr((void *)sp, size))
395395
{
396-
g_enclave_state = ENCLAVE_CRASHED;
396+
set_enclave_state(ENCLAVE_CRASHED);
397397
return SGX_ERROR_STACK_OVERRUN;
398398
}
399399

@@ -416,7 +416,7 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
416416
}
417417
else
418418
{
419-
g_enclave_state = ENCLAVE_CRASHED;
419+
set_enclave_state(ENCLAVE_CRASHED);
420420
return SGX_ERROR_STACK_OVERRUN;
421421
}
422422
}
@@ -486,6 +486,6 @@ extern "C" sgx_status_t trts_handle_exception(void *tcs)
486486
return SGX_SUCCESS;
487487

488488
default_handler:
489-
g_enclave_state = ENCLAVE_CRASHED;
489+
set_enclave_state(ENCLAVE_CRASHED);
490490
return SGX_ERROR_ENCLAVE_CRASHED;
491491
}

0 commit comments

Comments
 (0)