Skip to content

Commit 288abe3

Browse files
committed
Refactoring enclave-sample aligning sgx BKM.
- Buffer interface redesign to separate input and output - prevent untrusted pointer
1 parent bb944a7 commit 288abe3

2 files changed

Lines changed: 228 additions & 7 deletions

File tree

product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.config.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
<ReservedMemExecutable>1</ReservedMemExecutable>
99
<TCSNum>10</TCSNum>
1010
<TCSPolicy>1</TCSPolicy>
11-
<DisableDebug>0</DisableDebug>
11+
<!-- SECURITY FIX: Debug mode disabled for production enclave security -->
12+
<DisableDebug>1</DisableDebug>
1213
<MiscSelect>0</MiscSelect>
1314
<MiscMask>0xFFFFFFFF</MiscMask>
1415
</EnclaveConfiguration>

product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp

Lines changed: 226 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,140 @@ static EnclaveModule *enclave_module_list = NULL;
8181
static korp_mutex enclave_module_list_lock = OS_THREAD_MUTEX_INITIALIZER;
8282
#endif
8383

84+
/* SECURITY FIX: Handle table for secure EnclaveModule reference management */
85+
#define MAX_MODULES 128
86+
typedef struct HandleTableEntry {
87+
uint32 id;
88+
EnclaveModule *module_ref;
89+
bool in_use;
90+
} HandleTableEntry;
91+
92+
static HandleTableEntry module_table[MAX_MODULES] = { 0 };
93+
static uint32 next_module_id = 1;
94+
static korp_mutex module_table_lock = OS_THREAD_MUTEX_INITIALIZER;
95+
96+
/* SECURITY: Allocate secure handle for EnclaveModule, preventing pointer
97+
* exposure */
98+
static uint32
99+
allocate_module_handle(EnclaveModule *module)
100+
{
101+
uint32 handle_id = 0;
102+
103+
os_mutex_lock(&module_table_lock);
104+
105+
/* Find free slot */
106+
for (uint32 i = 0; i < MAX_MODULES; i++) {
107+
if (!module_table[i].in_use) {
108+
module_table[i].id = next_module_id++;
109+
module_table[i].module_ref = module;
110+
module_table[i].in_use = true;
111+
handle_id = module_table[i].id;
112+
break;
113+
}
114+
}
115+
116+
os_mutex_unlock(&module_table_lock);
117+
118+
if (handle_id == 0) {
119+
int bytes_written = 0;
120+
ocall_print(&bytes_written,
121+
"SECURITY WARNING: Module handle table full\n");
122+
}
123+
124+
return handle_id;
125+
}
126+
127+
/* SECURITY: Lookup EnclaveModule by handle ID, preventing direct pointer access
128+
*/
129+
static EnclaveModule *
130+
lookup_module_by_handle(uint32 handle_id)
131+
{
132+
EnclaveModule *module = NULL;
133+
134+
if (handle_id == 0)
135+
return NULL;
136+
137+
os_mutex_lock(&module_table_lock);
138+
139+
for (uint32 i = 0; i < MAX_MODULES; i++) {
140+
if (module_table[i].in_use && module_table[i].id == handle_id) {
141+
module = module_table[i].module_ref;
142+
break;
143+
}
144+
}
145+
146+
os_mutex_unlock(&module_table_lock);
147+
148+
return module;
149+
}
150+
151+
/* SECURITY FIX: Handle table for secure wasm_module_inst_t reference management
152+
*/
153+
#define MAX_INSTANCES 128
154+
typedef struct InstanceTableEntry {
155+
uint32 id;
156+
wasm_module_inst_t inst_ref;
157+
bool in_use;
158+
} InstanceTableEntry;
159+
160+
static InstanceTableEntry instance_table[MAX_INSTANCES] = { 0 };
161+
static uint32 next_instance_id = 1;
162+
static korp_mutex instance_table_lock = OS_THREAD_MUTEX_INITIALIZER;
163+
164+
/* SECURITY: Allocate secure handle for wasm_module_inst_t, preventing pointer
165+
* exposure */
166+
static uint32
167+
allocate_instance_handle(wasm_module_inst_t inst)
168+
{
169+
uint32 handle_id = 0;
170+
171+
os_mutex_lock(&instance_table_lock);
172+
173+
for (uint32 i = 0; i < MAX_INSTANCES; i++) {
174+
if (!instance_table[i].in_use) {
175+
instance_table[i].id = next_instance_id++;
176+
instance_table[i].inst_ref = inst;
177+
instance_table[i].in_use = true;
178+
handle_id = instance_table[i].id;
179+
break;
180+
}
181+
}
182+
183+
os_mutex_unlock(&instance_table_lock);
184+
185+
if (handle_id == 0) {
186+
int bytes_written = 0;
187+
ocall_print(&bytes_written,
188+
"SECURITY WARNING: Instance handle table full\n");
189+
}
190+
191+
return handle_id;
192+
}
193+
194+
/* SECURITY: Lookup wasm_module_inst_t by handle ID, preventing direct pointer
195+
* access */
196+
static wasm_module_inst_t
197+
lookup_instance_by_handle(uint32 handle_id)
198+
{
199+
wasm_module_inst_t inst = NULL;
200+
201+
if (handle_id == 0)
202+
return NULL;
203+
204+
os_mutex_lock(&instance_table_lock);
205+
206+
for (uint32 i = 0; i < MAX_INSTANCES; i++) {
207+
if (instance_table[i].in_use && instance_table[i].id == handle_id) {
208+
inst = instance_table[i].inst_ref;
209+
break;
210+
}
211+
}
212+
213+
os_mutex_unlock(&instance_table_lock);
214+
215+
return inst;
216+
}
217+
84218
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
85219
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
86220
#endif
@@ -277,7 +411,18 @@ handle_cmd_load_module(uint64 *args, uint32 argc)
277411
return;
278412
}
279413

280-
*(EnclaveModule **)args_org = enclave_module;
414+
/* SECURITY FIX: Return secure handle ID instead of direct pointer */
415+
uint32 enclave_module_id = allocate_module_handle(enclave_module);
416+
if (enclave_module_id == 0) {
417+
/* Handle table full - cleanup and return error */
418+
if (!enclave_module->is_xip_file)
419+
wasm_runtime_free(enclave_module);
420+
else
421+
os_munmap(enclave_module, (uint32)total_size);
422+
*(void **)args_org = NULL;
423+
return;
424+
}
425+
*(uint32 *)args_org = enclave_module_id;
281426

282427
#if WASM_ENABLE_LIB_RATS != 0
283428
/* Calculate the module hash */
@@ -368,7 +513,10 @@ static void
368513
handle_cmd_instantiate_module(uint64 *args, uint32 argc)
369514
{
370515
uint64 *args_org = args;
371-
EnclaveModule *enclave_module = *(EnclaveModule **)args++;
516+
/* SECURITY FIX: Use handle lookup instead of direct pointer from untrusted
517+
* host */
518+
uint32 module_handle_id = *(uint32 *)args++;
519+
EnclaveModule *enclave_module = lookup_module_by_handle(module_handle_id);
372520
uint32 stack_size = *(uint32 *)args++;
373521
uint32 heap_size = *(uint32 *)args++;
374522
char *error_buf = *(char **)args++;
@@ -377,7 +525,7 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
377525

378526
bh_assert(argc == 5);
379527

380-
if (!runtime_inited) {
528+
if (!runtime_inited || !enclave_module) {
381529
*(void **)args_org = NULL;
382530
return;
383531
}
@@ -389,7 +537,14 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
389537
return;
390538
}
391539

392-
*(wasm_module_inst_t *)args_org = module_inst;
540+
/* SECURITY FIX: Return secure handle ID instead of direct pointer */
541+
uint32 instance_id = allocate_instance_handle(module_inst);
542+
if (instance_id == 0) {
543+
wasm_runtime_deinstantiate(module_inst);
544+
*(void **)args_org = NULL;
545+
return;
546+
}
547+
*(uint32 *)args_org = instance_id;
393548

394549
LOG_VERBOSE("Instantiate module success.\n");
395550
}
@@ -515,7 +670,9 @@ static void
515670
handle_cmd_set_wasi_args(uint64 *args, int32 argc)
516671
{
517672
uint64 *args_org = args;
518-
EnclaveModule *enclave_module = *(EnclaveModule **)args++;
673+
/* SECURITY FIX: Use handle lookup instead of direct pointer from host */
674+
uint32 module_handle_id = *(uint32 *)args++;
675+
EnclaveModule *enclave_module = lookup_module_by_handle(module_handle_id);
519676
char **dir_list = *(char ***)args++;
520677
uint32 dir_list_size = *(uint32 *)args++;
521678
char **env_list = *(char ***)args++;
@@ -533,7 +690,48 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
533690

534691
bh_assert(argc == 10);
535692

536-
if (!runtime_inited) {
693+
if (!runtime_inited || !enclave_module) {
694+
*args_org = false;
695+
return;
696+
}
697+
698+
/* SECURITY FIX: Validate all pointer arrays before use */
699+
if (dir_list_size > 0
700+
&& (!dir_list
701+
|| !sgx_is_outside_enclave(dir_list,
702+
sizeof(char *) * dir_list_size))) {
703+
int bytes_written = 0;
704+
ocall_print(&bytes_written, "SECURITY ERROR: Invalid dir_list\n");
705+
*args_org = false;
706+
return;
707+
}
708+
709+
if (env_list_size > 0
710+
&& (!env_list
711+
|| !sgx_is_outside_enclave(env_list,
712+
sizeof(char *) * env_list_size))) {
713+
int bytes_written = 0;
714+
ocall_print(&bytes_written, "SECURITY ERROR: Invalid env_list\n");
715+
*args_org = false;
716+
return;
717+
}
718+
719+
if (wasi_argc > 0
720+
&& (!wasi_argv
721+
|| !sgx_is_outside_enclave(wasi_argv,
722+
sizeof(char *) * wasi_argc))) {
723+
int bytes_written = 0;
724+
ocall_print(&bytes_written, "SECURITY ERROR: Invalid wasi_argv\n");
725+
*args_org = false;
726+
return;
727+
}
728+
729+
if (addr_pool_list_size > 0
730+
&& (!addr_pool_list
731+
|| !sgx_is_outside_enclave(addr_pool_list,
732+
sizeof(char *) * addr_pool_list_size))) {
733+
int bytes_written = 0;
734+
ocall_print(&bytes_written, "SECURITY ERROR: Invalid addr_pool_list\n");
537735
*args_org = false;
538736
return;
539737
}
@@ -695,6 +893,28 @@ void
695893
ecall_handle_command(unsigned cmd, unsigned char *cmd_buf,
696894
unsigned cmd_buf_size)
697895
{
896+
/* SECURITY FIX: Validate buffer before processing */
897+
if (!cmd_buf || cmd_buf_size < sizeof(uint64)) {
898+
int bytes_written = 0;
899+
ocall_print(&bytes_written,
900+
"SECURITY ERROR: Invalid buffer parameters\n");
901+
return;
902+
}
903+
904+
if (!sgx_is_outside_enclave(cmd_buf, cmd_buf_size)) {
905+
int bytes_written = 0;
906+
ocall_print(&bytes_written,
907+
"SECURITY ERROR: Buffer not outside enclave\n");
908+
return;
909+
}
910+
911+
if (cmd_buf_size % sizeof(uint64) != 0) {
912+
int bytes_written = 0;
913+
ocall_print(&bytes_written,
914+
"SECURITY ERROR: Buffer alignment invalid\n");
915+
return;
916+
}
917+
698918
uint64 *args = (uint64 *)cmd_buf;
699919
uint32 argc = cmd_buf_size / sizeof(uint64);
700920

0 commit comments

Comments
 (0)