Selaa lähdekoodia

[Pal/Linux] Allocate threads' stacks using malloc

_DkVirtualMemoryAlloc() can allocate memory overlapping with
pal_control.user_address. In this case, thread stack could get corrupted
by LibOS, typically resulting in SEGV.
Isaku Yamahata 4 vuotta sitten
vanhempi
commit
912761b1e0
2 muutettua tiedostoa jossa 16 lisäystä ja 16 poistoa
  1. 3 3
      Pal/src/host/Linux/db_main.c
  2. 13 13
      Pal/src/host/Linux/db_threading.c

+ 3 - 3
Pal/src/host/Linux/db_main.c

@@ -236,12 +236,12 @@ void pal_linux_main (void * args)
         INIT_FAIL(PAL_ERROR_NOMEM, "Out of memory");
     SET_HANDLE_TYPE(first_thread, thread);
     first_thread->thread.tid = INLINE_SYSCALL(gettid, 0);
-    first_thread->thread.stack = NULL;
 
-    void * alt_stack = NULL;
-    _DkVirtualMemoryAlloc(&alt_stack, ALT_STACK_SIZE, 0, PAL_PROT_READ|PAL_PROT_WRITE);
+    void * alt_stack = malloc(ALT_STACK_SIZE);
     if (!alt_stack)
         INIT_FAIL(PAL_ERROR_NOMEM, "Out of memory");
+    memset(alt_stack, 0, ALT_STACK_SIZE);
+    first_thread->thread.stack = alt_stack;
 
     // Initialize TCB at the top of the alternative stack.
     PAL_TCB_LINUX * tcb = alt_stack + ALT_STACK_SIZE - sizeof(PAL_TCB_LINUX);

+ 13 - 13
Pal/src/host/Linux/db_threading.c

@@ -83,15 +83,18 @@ int pal_thread_init (void * tcbptr)
 int _DkThreadCreate (PAL_HANDLE * handle, int (*callback) (void *),
                      const void * param)
 {
-    void * stack = NULL;
-    int ret = _DkVirtualMemoryAlloc(&stack, THREAD_STACK_SIZE + ALT_STACK_SIZE,
-                                    0, PAL_PROT_READ|PAL_PROT_WRITE);
-    if (ret < 0)
-        return ret;
+    int ret = 0;
+    PAL_HANDLE hdl = NULL;
+    void * stack = malloc(THREAD_STACK_SIZE + ALT_STACK_SIZE);
+    if (!stack) {
+        ret = -ENOMEM;
+        goto err;
+    }
+    memset(stack, 0, THREAD_STACK_SIZE + ALT_STACK_SIZE);
 
     void * child_stack = stack + THREAD_STACK_SIZE;
 
-    PAL_HANDLE hdl = malloc(HANDLE_SIZE(thread));
+    hdl = malloc(HANDLE_SIZE(thread));
     if (!hdl) {
         ret = -ENOMEM;
         goto err;
@@ -124,10 +127,8 @@ int _DkThreadCreate (PAL_HANDLE * handle, int (*callback) (void *),
     *handle = hdl;
     return 0;
 err:
-    if (stack)
-        _DkVirtualMemoryFree(stack, THREAD_STACK_SIZE + ALT_STACK_SIZE);
-    if (hdl)
-        free(hdl);
+    free(stack);
+    free(hdl);
     return ret;
 }
 
@@ -181,12 +182,11 @@ noreturn void _DkThreadExit (void)
         // Take precautions to unset the TCB and alternative stack first.
         INLINE_SYSCALL(arch_prctl, 2, ARCH_SET_GS, 0);
         INLINE_SYSCALL(sigaltstack, 2, &ss, NULL);
-        INLINE_SYSCALL(munmap, 2, tcb->alt_stack, ALT_STACK_SIZE);
     }
 
-    if (handle && handle->thread.stack) {
+    if (handle) {
         // Free the thread stack
-        INLINE_SYSCALL(munmap, 2, handle->thread.stack, THREAD_STACK_SIZE);
+        free(handle->thread.stack);
         // After this line, needs to exit the thread immediately
     }