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