Diff for /embedaddon/php/main/fopen_wrappers.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/21 23:48:05 version 1.1.1.4, 2014/06/15 20:04:01
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2014 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | This source file is subject to version 3.01 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 39 Line 39
 #include <sys/param.h>  #include <sys/param.h>
 #endif  #endif
   
 #include "safe_mode.h"  
 #include "ext/standard/head.h"  #include "ext/standard/head.h"
 #include "ext/standard/php_standard.h"  #include "ext/standard/php_standard.h"
 #include "zend_compile.h"  #include "zend_compile.h"
Line 85  or a tightening during activation/runtime/deactivation Line 84  or a tightening during activation/runtime/deactivation
 PHPAPI ZEND_INI_MH(OnUpdateBaseDir)  PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
 {  {
         char **p, *pathbuf, *ptr, *end;          char **p, *pathbuf, *ptr, *end;
   #ifndef ZTS
           char *base = (char *) mh_arg2;
   #else
           char *base = (char *) ts_resource(*((int *) mh_arg2));
   #endif
   
        p = &PG(open_basedir);        p = (char **) (base + (size_t) mh_arg1);
   
         if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {          if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {
                 /* We're in a PHP_INI_SYSTEM context, no restrictions */                  /* We're in a PHP_INI_SYSTEM context, no restrictions */
Line 333  PHPAPI int php_check_open_basedir_ex(const char *path, Line 337  PHPAPI int php_check_open_basedir_ex(const char *path,
 }  }
 /* }}} */  /* }}} */
   
 /* {{{ php_check_safe_mode_include_dir  
  */  
 PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC)  
 {  
         if (PG(safe_mode)) {  
                 if (PG(safe_mode_include_dir) && *PG(safe_mode_include_dir)) {  
                         char *pathbuf;  
                         char *ptr;  
                         char *end;  
                         char resolved_name[MAXPATHLEN];  
   
                         /* Resolve the real path into resolved_name */  
                         if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {  
                                 return -1;  
                         }  
                         pathbuf = estrdup(PG(safe_mode_include_dir));  
                         ptr = pathbuf;  
   
                         while (ptr && *ptr) {  
                                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);  
                                 if (end != NULL) {  
                                         *end = '\0';  
                                         end++;  
                                 }  
   
                                 /* Check the path */  
 #ifdef PHP_WIN32  
                                 if (strncasecmp(ptr, resolved_name, strlen(ptr)) == 0)  
 #else  
                                 if (strncmp(ptr, resolved_name, strlen(ptr)) == 0)  
 #endif  
                                 {  
                                         /* File is in the right directory */  
                                         efree(pathbuf);  
                                         return 0;  
                                 }  
   
                                 ptr = end;  
                         }  
                         efree(pathbuf);  
                 }  
                 return -1;  
         }  
   
         /* Nothing to check... */  
         return 0;  
 }  
 /* }}} */  
   
 /* {{{ php_fopen_and_set_opened_path  /* {{{ php_fopen_and_set_opened_path
  */   */
 static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, char **opened_path TSRMLS_DC)  static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, char **opened_path TSRMLS_DC)
Line 393  static FILE *php_fopen_and_set_opened_path(const char  Line 348  static FILE *php_fopen_and_set_opened_path(const char 
         }          }
         fp = VCWD_FOPEN(path, mode);          fp = VCWD_FOPEN(path, mode);
         if (fp && opened_path) {          if (fp && opened_path) {
                *opened_path = expand_filepath(path, NULL TSRMLS_CC);                *opened_path = expand_filepath_with_mode(path, NULL, NULL, 0, CWD_EXPAND TSRMLS_CC);
         }          }
         return fp;          return fp;
 }  }
Line 403  static FILE *php_fopen_and_set_opened_path(const char  Line 358  static FILE *php_fopen_and_set_opened_path(const char 
  */   */
 PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)  PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
 {  {
         FILE *fp;  
 #ifndef PHP_WIN32  
         struct stat st;  
 #endif  
         char *path_info;          char *path_info;
         char *filename = NULL;          char *filename = NULL;
         char *resolved_path = NULL;          char *resolved_path = NULL;
         int length;          int length;
           zend_bool orig_display_errors;
   
         path_info = SG(request_info).request_uri;          path_info = SG(request_info).request_uri;
 #if HAVE_PWD_H  #if HAVE_PWD_H
Line 491  PHPAPI int php_fopen_primary_script(zend_file_handle * Line 443  PHPAPI int php_fopen_primary_script(zend_file_handle *
                 SG(request_info).path_translated = NULL;                  SG(request_info).path_translated = NULL;
                 return FAILURE;                  return FAILURE;
         }          }
        fp = VCWD_FOPEN(resolved_path, "rb");        efree(resolved_path);
   
#ifndef PHP_WIN32        orig_display_errors = PG(display_errors);
        /* refuse to open anything that is not a regular file */        PG(display_errors) = 0;
        if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) {        if (zend_stream_open(filename, file_handle TSRMLS_CC) == FAILURE) {
                fclose(fp);                PG(display_errors) = orig_display_errors;
                fp = NULL; 
        } 
#endif 
 
        if (!fp) { 
                 if (SG(request_info).path_translated != filename) {                  if (SG(request_info).path_translated != filename) {
                         STR_FREE(filename);                          STR_FREE(filename);
                 }                  }
Line 509  PHPAPI int php_fopen_primary_script(zend_file_handle * Line 456  PHPAPI int php_fopen_primary_script(zend_file_handle *
                 SG(request_info).path_translated = NULL;                  SG(request_info).path_translated = NULL;
                 return FAILURE;                  return FAILURE;
         }          }
           PG(display_errors) = orig_display_errors;
   
         file_handle->opened_path = resolved_path;  
   
         if (SG(request_info).path_translated != filename) {          if (SG(request_info).path_translated != filename) {
                 STR_FREE(SG(request_info).path_translated);     /* for same reason as above */                  STR_FREE(SG(request_info).path_translated);     /* for same reason as above */
                 SG(request_info).path_translated = filename;                  SG(request_info).path_translated = filename;
         }          }
   
         file_handle->filename = SG(request_info).path_translated;  
         file_handle->free_filename = 0;  
         file_handle->handle.fp = fp;  
         file_handle->type = ZEND_HANDLE_FP;  
   
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 537  PHPAPI char *php_resolve_path(const char *filename, in Line 478  PHPAPI char *php_resolve_path(const char *filename, in
         char *actual_path;          char *actual_path;
         php_stream_wrapper *wrapper;          php_stream_wrapper *wrapper;
   
        if (!filename) {        if (!filename || CHECK_NULL_PATH(filename, filename_length)) {
                 return NULL;                  return NULL;
         }          }
   
         if (strlen(filename) != filename_length) {  
                 return NULL;  
         }  
   
         /* Don't resolve paths which contain protocol (except of file://) */          /* Don't resolve paths which contain protocol (except of file://) */
         for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);          for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
         if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {          if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
Line 628  PHPAPI char *php_resolve_path(const char *filename, in Line 565  PHPAPI char *php_resolve_path(const char *filename, in
         /* check in calling scripts' current working directory as a fall back case          /* check in calling scripts' current working directory as a fall back case
          */           */
         if (zend_is_executing(TSRMLS_C)) {          if (zend_is_executing(TSRMLS_C)) {
                char *exec_fname = zend_get_executed_filename(TSRMLS_C);                const char *exec_fname = zend_get_executed_filename(TSRMLS_C);
                 int exec_fname_length = strlen(exec_fname);                  int exec_fname_length = strlen(exec_fname);
   
                 while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));                  while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
Line 674  PHPAPI char *php_resolve_path(const char *filename, in Line 611  PHPAPI char *php_resolve_path(const char *filename, in
 PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC)  PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC)
 {  {
         char *pathbuf, *ptr, *end;          char *pathbuf, *ptr, *end;
        char *exec_fname;        const char *exec_fname;
         char trypath[MAXPATHLEN];          char trypath[MAXPATHLEN];
         struct stat sb;  
         FILE *fp;          FILE *fp;
         int path_length;          int path_length;
         int filename_length;          int filename_length;
Line 693  PHPAPI FILE *php_fopen_with_path(const char *filename, Line 629  PHPAPI FILE *php_fopen_with_path(const char *filename,
         filename_length = strlen(filename);          filename_length = strlen(filename);
   
         /* Relative path open */          /* Relative path open */
        if (*filename == '.') {        if ((*filename == '.')
                if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) { 
                        return NULL; 
                } 
                return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC); 
        } 
 
        /* 
         * files in safe_mode_include_dir (or subdir) are excluded from 
         * safe mode GID/UID checks 
         */ 
 
         /* Absolute path open */          /* Absolute path open */
        if (IS_ABSOLUTE_PATH(filename, filename_length)) {         || IS_ABSOLUTE_PATH(filename, filename_length)
                if (php_check_safe_mode_include_dir(filename TSRMLS_CC) == 0) {         || (!path || (path && !*path))
                        /* filename is in safe_mode_include_dir (or subdir) */        ) {
                        return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC); 
                } 
                if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) { 
                        return NULL; 
                } 
                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);                  return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
         }          }
   
         if (!path || (path && !*path)) {  
                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {  
                         return NULL;  
                 }  
                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);  
         }  
   
         /* check in provided path */          /* check in provided path */
         /* append the calling scripts' current working directory          /* append the calling scripts' current working directory
          * as a fall back case           * as a fall back case
Line 759  PHPAPI FILE *php_fopen_with_path(const char *filename, Line 672  PHPAPI FILE *php_fopen_with_path(const char *filename,
                 if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) {                  if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) {
                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN);                          php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN);
                 }                  }
                 if (PG(safe_mode)) {  
                         if (VCWD_STAT(trypath, &sb) == 0) {  
                                 /* file exists ... check permission */  
                                 if (php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0 ||  
                                         php_checkuid(trypath, mode, CHECKUID_CHECK_MODE_PARAM)  
                                 ) {  
                                         /* UID ok, or trypath is in safe_mode_include_dir */  
                                         fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);  
                                 } else {  
                                         fp = NULL;  
                                 }  
                                 efree(pathbuf);  
                                 return fp;  
                         }  
                 }  
                 fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);                  fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);
                 if (fp) {                  if (fp) {
                         efree(pathbuf);                          efree(pathbuf);
Line 839  PHPAPI char *expand_filepath(const char *filepath, cha Line 737  PHPAPI char *expand_filepath(const char *filepath, cha
  */   */
 PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC)  PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC)
 {  {
           return expand_filepath_with_mode(filepath, real_path, relative_to, relative_to_len, CWD_FILEPATH TSRMLS_CC);
   }
   /* }}} */
   
   /* {{{ expand_filepath_use_realpath
    */
   PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode TSRMLS_DC)
   {
         cwd_state new_state;          cwd_state new_state;
         char cwd[MAXPATHLEN];          char cwd[MAXPATHLEN];
         int copy_len;          int copy_len;
Line 869  PHPAPI char *expand_filepath_ex(const char *filepath,  Line 775  PHPAPI char *expand_filepath_ex(const char *filepath, 
                                  * we cannot cannot getcwd() and the requested,                                   * we cannot cannot getcwd() and the requested,
                                  * relatively referenced file is accessible */                                   * relatively referenced file is accessible */
                                 copy_len = strlen(filepath) > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : strlen(filepath);                                  copy_len = strlen(filepath) > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : strlen(filepath);
                                real_path = estrndup(filepath, copy_len);                                if (real_path) {
                                         memcpy(real_path, filepath, copy_len);
                                         real_path[copy_len] = '\0';
                                 } else {
                                         real_path = estrndup(filepath, copy_len);
                                 }
                                 close(fdtest);                                  close(fdtest);
                                 return real_path;                                  return real_path;
                         } else {                          } else {
Line 883  PHPAPI char *expand_filepath_ex(const char *filepath,  Line 794  PHPAPI char *expand_filepath_ex(const char *filepath, 
         new_state.cwd = strdup(cwd);          new_state.cwd = strdup(cwd);
         new_state.cwd_length = strlen(cwd);          new_state.cwd_length = strlen(cwd);
   
        if (virtual_file_ex(&new_state, filepath, NULL, CWD_FILEPATH)) {        if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode TSRMLS_CC)) {
                 free(new_state.cwd);                  free(new_state.cwd);
                 return NULL;                  return NULL;
         }          }

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>