From: Zhiqi Song songzhiqi1@huawei.com
When enable 'dynamic_path' of uadk_engine in openssl.cnf, and execute speed tool with '-multi' param, the uadk_engine will be bind and init before fork() operation. The fork() operation will copy memory resources from parent process and get a child process.
As uadk_engine will register a function in child process with pthread_atfork(), the child process will call the async_module_init() and alloc new memory, the memory copied from parent process will leak.
And in multi-engine and mulit-fork scenario, if resources have been forked by other engines, and the uadk_engine performs the fork operation and executes services at this time, the uadk_engine will destroy the asynchronous resources from the fork in the subprocess. If other engines are occupying the threads before the fork and do not end. The pthread_join() in async_module_uninit() of the uadk_engine cannot wait for the corresponding thread, and the entire service process is suspended. The call stack when the program is suspended is as follows:
Thread 2 (Thread 0xffff9b4ff0a0 (LWP 3242840) "openssl"): 0 0x0000ffffa6423b00 in __futex_abstimed_wait_common64 1 __futex_abstimed_wait_common 2 __GI___futex_abstimed_wait_cancelable64 3 0x0000ffffa642f3e4 in do_futex_wait 4 0x0000ffffa642f4ac in __new_sem_wait_slow64 5 0x0000ffffa30a2170 in async_poll_process_func 6 0x0000ffffa64272f8 in start_thread 7 0x0000ffffa648ea1c in thread_start ()
To solve this, call uninit operation before creating subprocess to prevent resource leakage after the fork subprocess and ensure that the uadk_engine service can exit normally in multi-engine and multi-fork scenarios.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_engine_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/uadk_engine_init.c b/src/uadk_engine_init.c index bba382f..1a2b1d4 100644 --- a/src/uadk_engine_init.c +++ b/src/uadk_engine_init.c @@ -417,7 +417,7 @@ static int bind_fn(ENGINE *e, const char *id) bind_fn_uadk_alg(e);
if (uadk_cipher || uadk_digest || uadk_rsa || uadk_dh || uadk_ecc) - pthread_atfork(NULL, NULL, engine_init_child_at_fork_handler); + pthread_atfork(async_module_uninit, NULL, engine_init_child_at_fork_handler);
ret = ENGINE_set_ctrl_function(e, uadk_engine_ctrl); if (ret != 1) {