PHP 4.0 Bug #3697 Updated: open_basedir prevents creating files with fopen
| From: | Bug Database | Date: | Thu, 02 Mar 2000 06:24:46 +0000 |
| Subject: | PHP 4.0 Bug #3697 Updated: open_basedir prevents creating files with fopen | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-16257@lists.php.net to get a copy of this message | ||
ID: 3697
User Update by: djm@web.us.uu.net
Status: Open
Bug Type: Misbehaving function
Description: open_basedir prevents creating files with fopen
Some more warning messages to alert about exceptional conditions would be helpful. Also,
there's a misformatted warning message due to the appending of " in
<script>...".
And, there's a place in the distributed code that's missing the PHP_WIN32 case.
So here's my final (I think) suggested patch:
Index: fopen-wrappers.c
===================================================================
retrieving revision 1.2
diff -u -r1.2 fopen-wrappers.c
--- fopen-wrappers.c 2000/03/01 04:32:29 1.2
+++ fopen-wrappers.c 2000/03/02 06:14:53
@@ -120,21 +120,26 @@
}
/* Resolve the real path into resolved_name */
- if ((php_realpath(path, resolved_name) != NULL) && (php_realpath(local_open_basedir,
resolved_basedir) != NULL)) {
+ if (php_realpath(path, resolved_name) == NULL) {
+ /* Unable to resolve the real path, return -1 */
+ return -1;
+ } else if (php_realpath(local_open_basedir, resolved_basedir) == NULL) {
+ /* Unable to resolve the real path, return -1 */
+ php_error(E_WARNING, "cannot resolve open_basedir %s",
local_open_basedir);
+ return -1;
+ } else {
/* Check the path */
#ifdef PHP_WIN32
- if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) {
+ if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0)
#else
- if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) {
+ if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0)
#endif
+ {
/* File is in the right directory */
return 0;
} else {
return -1;
}
- } else {
- /* Unable to resolve the real path, return -1 */
- return -1;
}
}
@@ -170,7 +175,7 @@
ptr = end;
}
- php_error(E_WARNING, "open_basedir restriction in effect. File is in wrong
directory.");
+ php_error(E_WARNING, "open_basedir restriction in effect. File is in wrong
directory");
efree(pathbuf);
return -1;
}
Index: php_realpath.c
===================================================================
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 php_realpath.c
--- php_realpath.c 2000/03/01 04:23:33 1.1.1.1
+++ php_realpath.c 2000/03/02 06:20:56
@@ -97,6 +97,7 @@
if (getcwd(path_construction, MAXPATHLEN-1) == NULL) {
/* Unable to get cwd */
resolved_path[0] = 0;
+ php_error(E_WARNING, "cannot get current directory");
return NULL;
}
strcat(path_construction, "/");
@@ -213,7 +214,10 @@
/* Check the current location to see if it is a symlink */
if((linklength = readlink(path_construction, buf, MAXPATHLEN)) != -1) {
/* Check linkcount */
- if (linkcount > MAXSYMLINKS) return NULL;
+ if (linkcount > MAXSYMLINKS) {
+ php_error(E_WARNING, "detected symlink loop in %s", path);
+ return NULL;
+ }
/* Count this symlink */
linkcount++;
@@ -222,7 +226,10 @@
buf[linklength] = 0;
/* Check for overflow */
- if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) return NULL;
+ if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) {
+ php_error(E_WARNING, "overflow in %s", path);
+ return NULL;
+ }
/* Remove the symlink-component wrom path_construction */
writepos--; /* move to
'/' */
@@ -251,12 +258,31 @@
}
/* Check if the resolved path is a directory */
- if (stat(path_construction, &filestat) != 0) return NULL;
+ if (stat(path_construction, &filestat) != 0) {
+ /* It doesn't exist yet; check the directory it's in instead. */
+#ifdef PHP_WIN32
+ while (*--writepos != '\\' && writepos > path_construction)
+#else
+ while (*--writepos != '/' && writepos > path_construction)
+#endif
+ ;
+ *writepos = 0;
+ if (stat(path_construction, &filestat) != 0) {
+ return NULL;
+ }
+ }
if (S_ISDIR(filestat.st_mode)) {
/* It's a directory, append a / if needed */
+#ifdef PHP_WIN32
+ if (*(writepos-1) != '\\') {
+#else
if (*(writepos-1) != '/') {
+#endif
/* Check for overflow */
- if ((strlen(workpos) + 2) >= MAXPATHLEN) return NULL;
+ if ((strlen(workpos) + 2) >= MAXPATHLEN) {
+ php_error(E_WARNING, "overflow in %s", path);
+ return NULL;
+ }
*writepos++ = '/';
*writepos = 0;
Full Bug description available at: http://bugs.php.net/version4/?id=3697