From: [EMAIL PROTECTED] Operating system: Linux PHP version: 4.2.0 PHP Bug Type: Scripting Engine problem Bug description: Mkdir fails under safe mode
Unable to create directory by mkdir PHP function when PHP runs under safe mode. The following command fails: if (!mkdir("$PHP_DOCUMENT_ROOT/$path", 0770))when $path has a trailing slash. There is two possible solutions. Both shown below and can also be found at http://www.cf1.ru/~byg/patch/php/safe_mode.c.patch http://www.cf1.ru/~byg/patch/php/mkdir_get_rid_trailing_slashes.patch or ftp://ftp.cf1.ru/pub/patches/php/ 1) change php_checkuid in main/safe_mode.c 2) change mkdir handler in ext/standard/file.c 1st patch: ================================================= --- main/safe_mode.c.orig Thu Apr 4 13:58:00 2002 +++ main/safe_mode.c Tue Apr 16 12:29:53 2002 @@ -49,7 +49,7 @@ int ret, nofile=0; long uid=0L, gid=0L, duid=0L, dgid=0L; char path[MAXPATHLEN]; - char *s; + char *s, *anchor; TSRMLS_FETCH(); if (!filename) { @@ -105,19 +105,42 @@ *s = '\0'; } } else { /* CHECKUID_ALLOW_ONLY_DIR */ - s = strrchr(filename, DEFAULT_SLASH); - - if (s == filename) { - /* root dir */ - path[0] = DEFAULT_SLASH; - path[1] = '\0'; - } else if (s) { - *s = '\0'; + /* look for a trail slash --byg */ + s = (char *) strrchr(filename, DEFAULT_SLASH); + /* if s points s is either equal to or less than filename, NULL as last resort (never s>filename) */ + if ((filename + strlen(filename) - 1) > s) + { + if (s) + { /* path like /a/b or a/b, skip tail */ + *s='\0'; VCWD_REALPATH(filename, path); *s = DEFAULT_SLASH; - } else { + } + else + { /* trivial path like aaa */ VCWD_GETCWD(path, MAXPATHLEN); - } + } + } + else + { + /* get rid contiguous trailing slashes if any */ + while( s>filename && *(s-1) == DEFAULT_SLASH) + --s; + if (s > filename) + { /* mark current position then look for the next slash group */ + anchor = s; *s = '\0'; s = (char*) strrchr(filename, '/'); + if (s) *s = '\0'; /* path was either /a/b/// */ + VCWD_REALPATH(filename, path); /* or just a/// */ + *anchor = DEFAULT_SLASH; /* restore slashes */ + if (s) *s = DEFAULT_SLASH; + } + /* rare case - root dir */ + else + { + path[0] = DEFAULT_SLASH; + path[1] = '\0'; + } + } } /* end CHECKUID_ALLOW_ONLY_DIR */ if (mode != CHECKUID_ALLOW_ONLY_FILE) { ================================================== 2nd patch: ================================================== --- ext/standard/file.c.orig Tue Apr 16 22:34:55 2002 +++ ext/standard/file.c Tue Apr 16 23:19:29 2002 @@ -1454,10 +1454,21 @@ { int dir_len, ret; mode_t mode = 0777; - char *dir; + char *dir, *s; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &dir, &dir_len, &mode) == FAILURE) { return; + } + + /* get rid trailing slashes if any --byg */ + if (dir) { + s = dir + strlen(dir) - 1; + if (*s == DEFAULT_SLASH) { + while((*(s-1) == DEFAULT_SLASH) && (s > dir)) + --s; + if (s > dir) + *(s) = '\0'; + } } if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_ALLOW_ONLY_DIR))) { if (mode != CHECKUID_ALLOW_ONLY_FILE) { ===================================================== -- Edit bug report at http://bugs.php.net/?id=16638&edit=1 -- Fixed in CVS: http://bugs.php.net/fix.php?id=16638&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=16638&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=16638&r=needtrace Try newer version: http://bugs.php.net/fix.php?id=16638&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=16638&r=support Expected behavior: http://bugs.php.net/fix.php?id=16638&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=16638&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=16638&r=submittedtwice