From 45fe1045e5bdc8d44f6f237db1c4a006067a7fae Mon Sep 17 00:00:00 2001 From: ish1416 Date: Mon, 10 Nov 2025 09:41:17 +0530 Subject: [PATCH] aix,ibmi,os390: make uv_exepath thread-safe Fix thread-safety issue in uv_exepath() for AIX, IBM i, and z/OS platforms by adding mutex protection around uv__search_path() calls. The uv__search_path() function calls getenv("PATH") which is not thread-safe. This fix adds proper mutex synchronization to prevent race conditions when multiple threads call uv_exepath() concurrently. Changes: - aix-common.c: Add mutex protection around uv__search_path call - os390.c: Add mutex protection and use cached original_exepath when available - os390-proctitle.c: Make process_title_mutex and related functions non-static, add original_exepath variable - ibmi.c: Add mutex protection around uv__search_path call in uv_setup_args Fixes #4920 --- src/unix/aix-common.c | 5 ++++- src/unix/ibmi.c | 6 +++--- src/unix/os390-proctitle.c | 7 ++++--- src/unix/os390.c | 26 ++++++++++++++++++++++++-- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/unix/aix-common.c b/src/unix/aix-common.c index abc4c901a..3dc2e32b6 100644 --- a/src/unix/aix-common.c +++ b/src/unix/aix-common.c @@ -85,5 +85,8 @@ int uv_exepath(char* buffer, size_t* size) { if (res < 0) return UV_EINVAL; - return uv__search_path(args, buffer, size); + uv_mutex_lock(&process_title_mutex); + res = uv__search_path(args, buffer, size); + uv_mutex_unlock(&process_title_mutex); + return res; } diff --git a/src/unix/ibmi.c b/src/unix/ibmi.c index f4f8748a8..3aedb5cde 100644 --- a/src/unix/ibmi.c +++ b/src/unix/ibmi.c @@ -513,12 +513,12 @@ char** uv_setup_args(int argc, char** argv) { if (argc > 0) { /* Use argv[0] to determine value for uv_exepath(). */ size = sizeof(exepath); + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); if (uv__search_path(argv[0], exepath, &size) == 0) { - uv_once(&process_title_mutex_once, init_process_title_mutex_once); - uv_mutex_lock(&process_title_mutex); original_exepath = uv__strdup(exepath); - uv_mutex_unlock(&process_title_mutex); } + uv_mutex_unlock(&process_title_mutex); } return argv; diff --git a/src/unix/os390-proctitle.c b/src/unix/os390-proctitle.c index ccda97c9a..5a7d37abc 100644 --- a/src/unix/os390-proctitle.c +++ b/src/unix/os390-proctitle.c @@ -25,13 +25,14 @@ #include #include -static uv_mutex_t process_title_mutex; -static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +uv_mutex_t process_title_mutex; +uv_once_t process_title_mutex_once = UV_ONCE_INIT; +char* original_exepath = NULL; static char* process_title = NULL; static void* args_mem = NULL; -static void init_process_title_mutex_once(void) { +void init_process_title_mutex_once(void) { uv_mutex_init(&process_title_mutex); } diff --git a/src/unix/os390.c b/src/unix/os390.c index 029add414..23e074353 100644 --- a/src/unix/os390.c +++ b/src/unix/os390.c @@ -152,19 +152,41 @@ static int getexe(char* buf, size_t len) { * or through some libc APIs. The below approach is to parse the argv[0]'s pattern * and use it in conjunction with PATH environment variable to craft one. */ +extern char* original_exepath; +extern uv_mutex_t process_title_mutex; +extern uv_once_t process_title_mutex_once; +extern void init_process_title_mutex_once(void); + int uv_exepath(char* buffer, size_t* size) { int res; char args[PATH_MAX]; - int pid; + size_t cached_len; if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + if (original_exepath != NULL) { + cached_len = strlen(original_exepath); + *size -= 1; + if (*size > cached_len) + *size = cached_len; + memcpy(buffer, original_exepath, *size); + buffer[*size] = '\0'; + uv_mutex_unlock(&process_title_mutex); + return 0; + } + uv_mutex_unlock(&process_title_mutex); + res = getexe(args, sizeof(args)); if (res < 0) return UV_EINVAL; - return uv__search_path(args, buffer, size); + uv_mutex_lock(&process_title_mutex); + res = uv__search_path(args, buffer, size); + uv_mutex_unlock(&process_title_mutex); + return res; }