version 1.1.1.1, 2012/02/21 23:48:05
|
version 1.1.1.3, 2013/07/22 01:32:11
|
Line 2
|
Line 2
|
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| PHP Version 5 | |
| PHP Version 5 | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Copyright (c) 1997-2012 The PHP Group | | | Copyright (c) 1997-2013 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 883 PHPAPI char *expand_filepath_ex(const char *filepath,
|
Line 789 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; |
} |
} |