summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--ext/posix/posix.c44
-rw-r--r--ext/standard/filestat.c22
-rw-r--r--main/fopen_wrappers.c30
-rw-r--r--main/safe_mode.c10
5 files changed, 74 insertions, 33 deletions
diff --git a/NEWS b/NEWS
index 3d493125ca..79070f867e 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ PHP NEWS
- Added CURLOPT_TCP_NODELAY constant to Curl extension. (Sara)
- Improved proc_open(). Now on Windows it can run external commands not through
CMD.EXE. (Dmitry)
+- Fixed bug #40098 (php_fopen_primary_script() not thread safe). (Ilia)
- Fixed bug #40091 (spl_autoload_register with 2 instances of the same
class). (Ilia)
- Fixed bug #40083 (milter SAPI functions always return false/null). (Tony)
diff --git a/ext/posix/posix.c b/ext/posix/posix.c
index d3f2311d57..fe2c6631d0 100644
--- a/ext/posix/posix.c
+++ b/ext/posix/posix.c
@@ -555,8 +555,8 @@ PHP_FUNCTION(posix_ttyname)
zval **z_fd;
char *p;
int fd;
-#if HAVE_TTYNAME_R
- size_t buflen;
+#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
+ long buflen;
#endif
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &z_fd) == FAILURE) {
@@ -573,8 +573,11 @@ PHP_FUNCTION(posix_ttyname)
convert_to_long_ex(z_fd);
fd = Z_LVAL_PP(z_fd);
}
-#if HAVE_TTYNAME_R
+#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
buflen = sysconf(_SC_TTY_NAME_MAX);
+ if (buflen < 1) {
+ RETURN_FALSE;
+ }
p = emalloc(buflen);
if (ttyname_r(fd, p, buflen)) {
@@ -822,9 +825,9 @@ PHP_FUNCTION(posix_getgrnam)
char *name;
struct group *g;
int name_len;
-#if HAVE_GETGRNAM_R
+#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
struct group gbuf;
- int buflen;
+ long buflen;
char *buf;
#endif
@@ -832,8 +835,11 @@ PHP_FUNCTION(posix_getgrnam)
RETURN_FALSE;
}
-#if HAVE_GETGRNAM_R
+#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (buflen < 1) {
+ RETURN_FALSE;
+ }
buf = emalloc(buflen);
g = &gbuf;
@@ -855,7 +861,7 @@ PHP_FUNCTION(posix_getgrnam)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix group to array");
RETVAL_FALSE;
}
-#if HAVE_GETGRNAM_R
+#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
efree(buf);
#endif
}
@@ -870,7 +876,7 @@ PHP_FUNCTION(posix_getgrgid)
int ret;
struct group _g;
struct group *retgrptr;
- int grbuflen;
+ long grbuflen;
char *grbuf;
#endif
struct group *g;
@@ -932,9 +938,9 @@ PHP_FUNCTION(posix_getpwnam)
struct passwd *pw;
char *name;
int name_len;
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
struct passwd pwbuf;
- int buflen;
+ long buflen;
char *buf;
#endif
@@ -942,8 +948,11 @@ PHP_FUNCTION(posix_getpwnam)
RETURN_FALSE;
}
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (buflen < 1) {
+ RETURN_FALSE;
+ }
buf = emalloc(buflen);
pw = &pwbuf;
@@ -965,7 +974,7 @@ PHP_FUNCTION(posix_getpwnam)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
RETVAL_FALSE;
}
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
efree(buf);
#endif
}
@@ -976,10 +985,10 @@ PHP_FUNCTION(posix_getpwnam)
PHP_FUNCTION(posix_getpwuid)
{
long uid;
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
struct passwd _pw;
struct passwd *retpwptr = NULL;
- int pwbuflen;
+ long pwbuflen;
char *pwbuf;
int ret;
#endif
@@ -988,8 +997,11 @@ PHP_FUNCTION(posix_getpwuid)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &uid) == FAILURE) {
RETURN_FALSE;
}
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (pwbuflen < 1) {
+ RETURN_FALSE;
+ }
pwbuf = emalloc(pwbuflen);
ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
@@ -1012,7 +1024,7 @@ PHP_FUNCTION(posix_getpwuid)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to convert posix passwd struct to array");
RETVAL_FALSE;
}
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
efree(pwbuf);
#endif
}
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 71eb2ebdfc..b68dec9366 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -363,12 +363,17 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp)
}
convert_to_string_ex(filename);
if (Z_TYPE_PP(group) == IS_STRING) {
-#if HAVE_GETGRNAM_R
+#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
struct group gr;
struct group *retgrptr;
- int grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
- char *grbuf = emalloc(grbuflen);
+ long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ char *grbuf;
+ if (grbuflen < 1) {
+ RETURN_FALSE;
+ }
+
+ grbuf = emalloc(grbuflen);
if (getgrnam_r(Z_STRVAL_PP(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_PP(group));
efree(grbuf);
@@ -454,12 +459,17 @@ static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown)
}
convert_to_string_ex(filename);
if (Z_TYPE_PP(user) == IS_STRING) {
-#if defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
+#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
struct passwd pw;
struct passwd *retpwptr = NULL;
- int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
- char *pwbuf = emalloc(pwbuflen);
+ long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ char *pwbuf;
+
+ if (pwbuflen < 1) {
+ RETURN_FALSE;
+ }
+ pwbuf = emalloc(pwbuflen);
if (getpwnam_r(Z_STRVAL_PP(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_PP(user));
efree(pwbuf);
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 5a3c4f6779..4e87a8a110 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -264,23 +264,37 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
filename = SG(request_info).path_translated;
path_info = SG(request_info).request_uri;
#if HAVE_PWD_H
- if (PG(user_dir) && *PG(user_dir)
- && path_info && '/' == path_info[0] && '~' == path_info[1]) {
-
- char user[32];
- struct passwd *pw;
+ if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) {
char *s = strchr(path_info + 2, '/');
filename = NULL; /* discard the original filename, it must not be used */
if (s) { /* if there is no path name after the file, do not bother */
- /* to try open the directory */
+ char user[32]; /* to try open the directory */
+ struct passwd *pw;
+#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
+ long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ char *pwbuf;
+
+ if (pwbuflen < 1) {
+ return FAILURE;
+ }
+
+ pwbuf = emalloc(pwbuflen);
+#endif
length = s - (path_info + 2);
- if (length > (int)sizeof(user) - 1)
+ if (length > (int)sizeof(user) - 1) {
length = sizeof(user) - 1;
+ }
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)) {
+ efree(pwbuf);
+ return FAILURE;
+ }
+#else
pw = getpwnam(user);
+#endif
if (pw && pw->pw_dir) {
filename = emalloc(strlen(PG(user_dir)) + strlen(path_info) + strlen(pw->pw_dir) + 4);
if (filename) {
diff --git a/main/safe_mode.c b/main/safe_mode.c
index d87c3f3e3f..ad17d482ca 100644
--- a/main/safe_mode.c
+++ b/main/safe_mode.c
@@ -228,12 +228,16 @@ PHPAPI char *php_get_current_user()
return SG(request_info).current_user;
#else
struct passwd *pwd;
-#ifdef HAVE_GETPWUID_R
+#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 = emalloc(pwbuflen);
+ char *pwbuf;
+ if (pwbuflen < 1) {
+ return ""
+ }
+ pwbuf = emalloc(pwbuflen);
if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
efree(pwbuf);
return "";
@@ -246,7 +250,7 @@ PHPAPI char *php_get_current_user()
#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);
-#ifdef HAVE_GETPWUID_R
+#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
efree(pwbuf);
#endif
return SG(request_info).current_user;