Bug #16638 Updated: Mkdir fails under safe mode

From: Date: Sat, 13 Jul 2002 04:45:29 +0000
Subject: Bug #16638 Updated: Mkdir fails under safe mode
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-14045@lists.php.net to get a copy of this message
ID: 16638 Updated by: sniper@php.net Reported By: byg@cf1.ru -Status: Open +Status: Closed Bug Type: Scripting Engine problem Operating System: Linux PHP Version: 4.2.0 New Comment: This bug has been fixed in CVS. You can grab a snapshot of the CVS version at http://snaps.php.net/. In case this was a documentation problem, the fix will show up soon at http://www.php.net/manual/. In case this was a PHP.net website problem, the change will show up on the PHP.net site and on the mirror sites. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2002-04-16 12:40:12] byg@cf1.ru 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 this bug report at http://bugs.php.net/?id=16638&edit=1

« previous php.bugs (#14045) next »