diff options
Diffstat (limited to 'main/fopen_wrappers.c')
| -rw-r--r-- | main/fopen_wrappers.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 015be9703..d171ea9a3 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.c 298277 2010-04-21 22:22:31Z felipe $ */ +/* $Id: fopen_wrappers.c 305698 2010-11-23 22:14:54Z pajoye $ */ /* {{{ includes */ @@ -173,21 +173,27 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path memcpy(path_tmp, resolved_name, path_len + 1); /* safe */ while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) { -#ifdef HAVE_SYMLINK - if (nesting_level == 0) { - int ret; - char buf[MAXPATHLEN]; - - ret = readlink(path_tmp, buf, MAXPATHLEN - 1); - if (ret < 0) { - /* not a broken symlink, move along.. */ - } else { - /* put the real path into the path buffer */ - memcpy(path_tmp, buf, ret); - path_tmp[ret] = '\0'; +#if defined(PHP_WIN32) || defined(HAVE_SYMLINK) +#if defined(PHP_WIN32) + if (EG(windows_version_info).dwMajorVersion > 5) { +#endif + if (nesting_level == 0) { + int ret; + char buf[MAXPATHLEN]; + + ret = php_sys_readlink(path_tmp, buf, MAXPATHLEN - 1); + if (ret < 0) { + /* not a broken symlink, move along.. */ + } else { + /* put the real path into the path buffer */ + memcpy(path_tmp, buf, ret); + path_tmp[ret] = '\0'; + } } +#if defined(PHP_WIN32) } #endif +#endif #if defined(PHP_WIN32) || defined(NETWARE) path_file = strrchr(path_tmp, DEFAULT_SLASH); @@ -228,6 +234,9 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR; resolved_basedir[++resolved_basedir_len] = '\0'; } + } else { + resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR; + resolved_basedir[resolved_basedir_len] = '\0'; } resolved_name_len = strlen(resolved_name); @@ -244,8 +253,13 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path #else if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { #endif - /* File is in the right directory */ - return 0; + if (resolved_name_len > resolved_basedir_len && + resolved_name[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) { + return -1; + } else { + /* File is in the right directory */ + return 0; + } } else { /* /openbasedir/ and /openbasedir are the same directory */ if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { @@ -281,6 +295,14 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) char *ptr; char *end; + /* Check if the path is too long so we can give a more useful error + * message. */ + if (strlen(path) > (MAXPATHLEN - 1)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path); + errno = EINVAL; + return -1; + } + pathbuf = estrdup(PG(open_basedir)); ptr = pathbuf; @@ -519,6 +541,10 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c return NULL; } + if (strlen(filename) != filename_length) { + return NULL; + } + /* Don't resolve paths which contain protocol (except of file://) */ for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) { |
