--- php-7.4.4/ext/posix/posix.c 2020-03-17 10:40:22.000000000 +0000 +++ php-7.4.4/ext/posix/posix.c 2020-03-27 03:19:13.133440186 +0000 @@ -1084,8 +1084,11 @@ PHP_FUNCTION(posix_getgrnam) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) + errno = 0; buflen = sysconf(_SC_GETGR_R_SIZE_MAX); - if (buflen < 1) { + if (buflen == -1 && errno == 0) { + buflen = 1024; + } else if (buflen < 1) { RETURN_FALSE; } buf = emalloc(buflen); @@ -1127,9 +1130,7 @@ PHP_FUNCTION(posix_getgrgid) { zend_long gid; #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX) - int ret; struct group _g; - struct group *retgrptr = NULL; long grbuflen; char *grbuf; #endif @@ -1141,20 +1142,27 @@ PHP_FUNCTION(posix_getgrgid) #if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX) + errno = 0; grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); - if (grbuflen < 1) { + if (grbuflen == -1 && errno == 0) { + grbuflen = 1024; + } else if (grbuflen < 1) { RETURN_FALSE; } - grbuf = emalloc(grbuflen); +try_again: + g = &_g; - ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr); - if (ret || retgrptr == NULL) { - POSIX_G(last_error) = ret; + if (getgrgid_r(gid, g, grbuf, grbuflen, &g) || g == NULL) { + if (errno == ERANGE) { + grbuflen *= 2; + grbuf = erealloc(grbuf, grbuflen); + goto try_again; + } + POSIX_G(last_error) = errno; efree(grbuf); RETURN_FALSE; } - g = &_g; #else if (NULL == (g = getgrgid(gid))) { POSIX_G(last_error) = errno; @@ -1210,14 +1218,23 @@ PHP_FUNCTION(posix_getpwnam) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) + errno = 0; buflen = sysconf(_SC_GETPW_R_SIZE_MAX); - if (buflen < 1) { + if (buflen == -1 && errno == 0) { + buflen = 1024; + } else if (buflen < 1) { RETURN_FALSE; } buf = emalloc(buflen); +try_again: pw = &pwbuf; if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) { + if (errno == ERANGE) { + buflen *= 2; + buf = erealloc(buf, buflen); + goto try_again; + } efree(buf); POSIX_G(last_error) = errno; RETURN_FALSE; @@ -1248,10 +1265,8 @@ PHP_FUNCTION(posix_getpwuid) zend_long uid; #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R) struct passwd _pw; - struct passwd *retpwptr = NULL; long pwbuflen; char *pwbuf; - int ret; #endif struct passwd *pw; @@ -1260,19 +1275,27 @@ PHP_FUNCTION(posix_getpwuid) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R) + errno = 0; pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); - if (pwbuflen < 1) { + if (pwbuflen == -1 && errno == 0) { + pwbuflen = 1024; + } else if (pwbuflen < 1) { RETURN_FALSE; } pwbuf = emalloc(pwbuflen); +try_again: + pw = &_pw; - ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr); - if (ret || retpwptr == NULL) { - POSIX_G(last_error) = ret; + if (getpwuid_r(uid, pw, pwbuf, pwbuflen, &pw) || pw == NULL) { + if (errno == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } + POSIX_G(last_error) = errno; efree(pwbuf); RETURN_FALSE; } - pw = &_pw; #else if (NULL == (pw = getpwuid(uid))) { POSIX_G(last_error) = errno; --- php-7.4.4/ext/standard/filestat.c 2020-03-17 10:40:30.000000000 +0000 +++ php-7.4.4/ext/standard/filestat.c 2020-03-27 04:00:18.333479165 +0000 @@ -302,15 +302,25 @@ PHPAPI int php_get_gid_by_name(const cha #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) struct group gr; struct group *retgrptr; + errno = 0; long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); char *grbuf; - if (grbuflen < 1) { + if (grbuflen == -1 && errno == 0) { + grbuflen = 1024; + } else if (grbuflen < 1) { return FAILURE; } grbuf = emalloc(grbuflen); - if (getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) { +try_again: + retgrptr = &gr; + if (getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr) || retgrptr == NULL) { + if (errno == ERANGE) { + grbuflen *= 2; + grbuf = erealloc(grbuf, grbuflen); + goto try_again; + } efree(grbuf); return FAILURE; } @@ -438,15 +448,25 @@ PHPAPI uid_t php_get_uid_by_name(const c #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) struct passwd pw; struct passwd *retpwptr = NULL; + errno = 0; long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; - if (pwbuflen < 1) { + if (pwbuflen == -1 && errno == 0) { + pwbuflen = 1024; + } else if (pwbuflen < 1) { return FAILURE; } pwbuf = emalloc(pwbuflen); - if (getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) { +try_again: + retpwptr = &pw; + if (getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr) || retpwptr == NULL) { + if (errno == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return FAILURE; } --- php-7.4.4/main/fopen_wrappers.c 2020-03-17 10:40:21.000000000 +0000 +++ php-7.4.4/main/fopen_wrappers.c 2020-03-27 04:08:46.553487201 +0000 @@ -366,10 +366,13 @@ PHPAPI int php_fopen_primary_script(zend struct passwd *pw; #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) struct passwd pwstruc; + errno = 0; long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; - if (pwbuflen < 1) { + if (pwbuflen == -1 && errno == 0) { + pwbuflen = 1024; + } else if (pwbuflen < 1) { return FAILURE; } @@ -382,7 +385,14 @@ PHPAPI int php_fopen_primary_script(zend memcpy(user, path_info + 2, length); user[length] = '\0'; #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) - if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) { +try_again: + pw = &pwstruc; + if (getpwnam_r(user, pw, pwbuf, pwbuflen, &pw) || pw == NULL) { + if (errno == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return FAILURE; } --- php-7.4.4/main/main.c 2020-03-17 10:40:21.000000000 +0000 +++ php-7.4.4/main/main.c 2020-03-27 03:33:22.663453619 +0000 @@ -1487,23 +1487,27 @@ PHPAPI char *php_get_current_user(void) struct passwd *pwd; #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) struct passwd _pw; - struct passwd *retpwptr = NULL; + errno = 0; int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; - if (pwbuflen < 1) { + if (pwbuflen == -1 && errno == 0) { + pwbuflen = 1024; + } else if (pwbuflen < 1) { return ""; } pwbuf = emalloc(pwbuflen); - if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) { - efree(pwbuf); - return ""; - } - if (retpwptr == NULL) { +try_again: + pwd = &_pw; + if (getpwuid_r(pstat->st_uid, pwd, pwbuf, pwbuflen, &pwd) || pwd == NULL) { + if (errno == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return ""; } - pwd = &_pw; #else if ((pwd=getpwuid(pstat->st_uid))==NULL) { return "";