From 385ede4a28c5c325a1b023ac7c1059ec9af9d4d1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 23:12:46 +0200 Subject: [PATCH 1/3] Split off UID to username translation of php_get_current_user() --- main/main.c | 98 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/main/main.c b/main/main.c index 18c8e2dfac7ec..3d7fe536d2adf 100644 --- a/main/main.c +++ b/main/main.c @@ -1492,6 +1492,56 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c } /* }}} */ +#ifndef PHP_WIN32 +static char *php_translate_uid_to_username(uid_t uid, size_t *len) +{ + struct passwd *pwd; +#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) + struct passwd _pw; + struct passwd *retpwptr = NULL; + int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); + char *pwbuf; + int err; + + if (pwbuflen < 1) { + pwbuflen = 1024; + } +# if ZEND_DEBUG + /* Test retry logic */ + pwbuflen = 1; +# endif + pwbuf = emalloc(pwbuflen); + +try_again: + err = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr); + if (err != 0) { + if (err == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } + efree(pwbuf); + return NULL; + } + if (retpwptr == NULL) { + efree(pwbuf); + return NULL; + } + pwd = &_pw; +#else + if ((pwd=getpwuid(uid))==NULL) { + return NULL; + } +#endif + *len = strlen(pwd->pw_name); + char *result = estrndup(pwd->pw_name, *len); +#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) + efree(pwbuf); +#endif + return result; +} +#endif + /* {{{ php_get_current_user */ PHPAPI char *php_get_current_user(void) { @@ -1524,50 +1574,14 @@ PHPAPI char *php_get_current_user(void) free(name); return SG(request_info).current_user; #else - struct passwd *pwd; -#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) - struct passwd _pw; - struct passwd *retpwptr = NULL; - int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); - char *pwbuf; - int err; - - if (pwbuflen < 1) { - pwbuflen = 1024; - } -# if ZEND_DEBUG - /* Test retry logic */ - pwbuflen = 1; -# endif - pwbuf = emalloc(pwbuflen); - -try_again: - err = getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr); - if (err != 0) { - if (err == ERANGE) { - pwbuflen *= 2; - pwbuf = erealloc(pwbuf, pwbuflen); - goto try_again; - } - efree(pwbuf); + size_t len; + char *username = php_translate_uid_to_username(pstat->st_uid, &len); + if (!username) { return ""; } - if (retpwptr == NULL) { - efree(pwbuf); - return ""; - } - pwd = &_pw; -#else - if ((pwd=getpwuid(pstat->st_uid))==NULL) { - return ""; - } -#endif - SG(request_info).current_user_length = strlen(pwd->pw_name); - SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length); -#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) - efree(pwbuf); -#endif - return SG(request_info).current_user; + SG(request_info).current_user_length = (int) len; + SG(request_info).current_user = username; + return username; #endif } } From 65d5efd761d8c821c1a3fc1bb061aa6eb717b1cb Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 23:26:35 +0200 Subject: [PATCH 2/3] Add php_get_current_running_user() API --- UPGRADING.INTERNALS | 2 ++ main/main.c | 16 ++++++++++++++++ main/php.h | 1 + 3 files changed, 19 insertions(+) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 2af2d4ce1c57d..f3c63e086d647 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -17,6 +17,8 @@ PHP 8.5 INTERNALS UPGRADE NOTES - Core . PG(arg_separator).input and PG(arg_separator).output are now `zend_string*` instead of `char*`. + . Added php_get_current_running_user() API to get the (effective) user + running the script. - Zend . Added zend_safe_assign_to_variable_noref() function to safely assign diff --git a/main/main.c b/main/main.c index 3d7fe536d2adf..30f73b5903c15 100644 --- a/main/main.c +++ b/main/main.c @@ -1542,6 +1542,22 @@ static char *php_translate_uid_to_username(uid_t uid, size_t *len) } #endif +PHPAPI char *php_get_current_running_user(size_t *len) +{ +#ifdef PHP_WIN32 + char *name = php_win32_get_username(); + if (!name) { + return NULL; + } + *len = strlen(name); + char *result = estrndup(name, *len); + free(name); + return result; +#else + return php_translate_uid_to_username(geteuid(), len); +#endif +} + /* {{{ php_get_current_user */ PHPAPI char *php_get_current_user(void) { diff --git a/main/php.h b/main/php.h index 5c0b89c328375..6b82bad8b53ac 100644 --- a/main/php.h +++ b/main/php.h @@ -337,6 +337,7 @@ PHPAPI int php_register_internal_extensions(void); PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata); PHPAPI void php_com_initialize(void); PHPAPI char *php_get_current_user(void); +PHPAPI char *php_get_current_running_user(size_t *len); PHPAPI const char *php_get_internal_encoding(void); PHPAPI const char *php_get_input_encoding(void); From 3f2a6e934b6cac23194d5a10d63493e391a6cc75 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 23:27:56 +0200 Subject: [PATCH 3/3] Fix bug #61094: Wrong WSDL cache file name While filed as a request, this can actually cause problems with cache files. If there are multiple users running the same SOAP code, then they will attempt to use the same cache file, even if they don't have permission to that. See https://github.com/php/php-src/issues/12838#issue-2018822658 for a concrete example. --- ext/soap/php_sdl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 5826c82c644ed..decf1d6664408 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -3185,22 +3185,23 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) unsigned char digest[16]; size_t len = strlen(SOAP_GLOBAL(cache_dir)); time_t cached; - char *user = php_get_current_user(); - size_t user_len = user ? strlen(user) + 1 : 0; + size_t user_len = 0; + char *user = php_get_current_running_user(&user_len); md5str[0] = '\0'; PHP_MD5Init(&md5_context); PHP_MD5Update(&md5_context, (unsigned char*)uri, uri_len); PHP_MD5Final(digest, &md5_context); make_digest(md5str, digest); - key = emalloc(len+sizeof("/wsdl-")-1+user_len+2+sizeof(md5str)); + key = emalloc(len+sizeof("/wsdl-")-1+user_len+1+2+sizeof(md5str)); memcpy(key,SOAP_GLOBAL(cache_dir),len); memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1); len += sizeof("/wsdl-")-1; if (user_len) { - memcpy(key+len, user, user_len-1); - len += user_len-1; + memcpy(key+len, user, user_len); + len += user_len; key[len++] = '-'; + efree(user); } if (WSDL_CACHE_VERSION <= 0x9f) { key[len++] = (WSDL_CACHE_VERSION >> 8) + '0';