--- php-4.3.10/main/safe_mode.c.orig 2005-02-09 15:40:53.000000000 +0100 +++ php-4.3.10/main/safe_mode.c 2005-02-09 15:46:45.000000000 +0100 @@ -50,6 +50,8 @@ PHPAPI int php_checkuid_ex(const char *f int ret, nofile=0; long uid=0L, gid=0L, duid=0L, dgid=0L; char path[MAXPATHLEN]; + char path_bak[MAXPATHLEN]; + char *s_bak; char *s, filenamecopy[MAXPATHLEN]; php_stream_wrapper *wrapper = NULL; TSRMLS_FETCH(); @@ -137,27 +139,46 @@ PHPAPI int php_checkuid_ex(const char *f } /* end CHECKUID_ALLOW_ONLY_DIR */ if (mode != CHECKUID_ALLOW_ONLY_FILE) { - /* check directory */ - ret = VCWD_STAT(path, &sb); - if (ret < 0) { - if ((flags & CHECKUID_NO_ERRORS) == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); + strcpy(path_bak, path); + while (!((path[0] == DEFAULT_SLASH) && (path[1] == '\0')) || (path[0] == '\0')) { + /* check directory */ + ret = VCWD_STAT(path, &sb); + if (ret < 0) { + if ((flags & CHECKUID_NO_ERRORS) == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); + } + return 0; + } + duid = sb.st_uid; + dgid = sb.st_gid; + if (duid == php_getuid()) { + return 1; + } else if (PG(safe_mode_gid) && dgid == php_getgid()) { + return 1; + } else if ((duid == getuid()) || (PG(safe_mode_gid) && dgid == getgid())) { + // ok, cycle again + } else { + goto while_end; } - return 0; - } - duid = sb.st_uid; - dgid = sb.st_gid; - if (duid == php_getuid()) { - return 1; - } else if (PG(safe_mode_gid) && dgid == php_getgid()) { - return 1; - } else { - TSRMLS_FETCH(); - if (SG(rfc1867_uploaded_files)) { - if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) { - return 1; - } + if (s_bak = strrchr(path, DEFAULT_SLASH)) { + if (s_bak == path) { + goto while_end; + } else { + *s_bak = '\0'; + } + } else { + goto while_end; + } + } // while ($path != '') +while_end: + strcpy(path, path_bak); + + TSRMLS_FETCH(); + + if (SG(rfc1867_uploaded_files)) { + if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) { + return 1; } } }