Fix potential recursive lock in pthread_create_wrapper (#2980)

Potential recursive lock occurs in:
```
pthread_create_wrapper   (acquire exec_env->wait_lock)
  => wasm_cluster_create_thread
    => allocate_aux_stack
      => wasm_runtime_module_malloc_internal
        => wasm_call_function
          => wasm_exec_env_set_thread_info (acquire exec_env->wait_lock again)
```
Allocate aux stack before calling wasm_cluster_create_thread to resolve it.

Reported in https://github.com/bytecodealliance/wasm-micro-runtime/pull/2977.
This commit is contained in:
Wenyong Huang
2024-01-08 09:43:31 +08:00
committed by GitHub
parent 4a1ad9a160
commit c39214e8a5
4 changed files with 64 additions and 22 deletions

View File

@ -558,6 +558,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
ThreadRoutineArgs *routine_args = NULL;
uint32 thread_handle;
uint32 stack_size = 8192;
uint32 aux_stack_start = 0, aux_stack_size;
int32 ret = -1;
bh_assert(module);
@ -609,10 +610,22 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
routine_args->info_node = info_node;
routine_args->module_inst = new_module_inst;
/* Allocate aux stack previously since exec_env->wait_lock is acquired
below, and if the stack is allocated in wasm_cluster_create_thread,
runtime may call the exported malloc function to allocate the stack,
which acquires exec_env->wait again in wasm_exec_env_set_thread_info,
and recursive lock (or hang) occurs */
if (!wasm_cluster_allocate_aux_stack(exec_env, &aux_stack_start,
&aux_stack_size)) {
LOG_ERROR("thread manager error: "
"failed to allocate aux stack space for new thread");
goto fail;
}
os_mutex_lock(&exec_env->wait_lock);
ret =
wasm_cluster_create_thread(exec_env, new_module_inst, true,
pthread_start_routine, (void *)routine_args);
ret = wasm_cluster_create_thread(
exec_env, new_module_inst, true, aux_stack_start, aux_stack_size,
pthread_start_routine, (void *)routine_args);
if (ret != 0) {
os_mutex_unlock(&exec_env->wait_lock);
goto fail;
@ -636,6 +649,8 @@ fail:
wasm_runtime_free(info_node);
if (routine_args)
wasm_runtime_free(routine_args);
if (aux_stack_start)
wasm_cluster_free_aux_stack(exec_env, aux_stack_start);
return ret;
}