diff options
author | Pierre Joye <pajoye@php.net> | 2007-03-14 11:22:13 +0000 |
---|---|---|
committer | Pierre Joye <pajoye@php.net> | 2007-03-14 11:22:13 +0000 |
commit | 133c226f569c9e5bfc5290cbb360c01a0994a21f (patch) | |
tree | 3a510e9d5a89791a9296c88ea1fb9e34563b94a0 | |
parent | e46b1b3747e85d219b74c7489d3a187ce08f3e24 (diff) | |
download | php-git-133c226f569c9e5bfc5290cbb360c01a0994a21f.tar.gz |
- MFB:
- rename SAFEMODE_CHECKFILE to OPENBASEDIR_CHECKPATH (can be used without
confusing in head without confusion)
- Add safemode and open basedir checks in zip:// wrapper (revert Ilia's
patch). Bug found by Stefan Esser in his MOPB-20-2007
-rw-r--r-- | ext/zip/php_zip.c | 18 | ||||
-rw-r--r-- | ext/zip/php_zip.h | 10 | ||||
-rw-r--r-- | ext/zip/zip_stream.c | 10 |
3 files changed, 38 insertions, 0 deletions
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 78f268a7fa..c49e169c01 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -122,6 +122,11 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil } php_basename(file, file_len, NULL, 0, &file_basename, (unsigned int *)&file_basename_len TSRMLS_CC); + if (OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { + efree(file_dirname_fullpath); + efree(file_basename); + return 0; + } } /* let see if the path already exists */ if (php_stream_stat_path(file_dirname_fullpath, &ssb) < 0) { @@ -149,6 +154,16 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil return 0; } + /* check again the full path, not sure if it + * is required, does a file can have a different + * safemode status as its parent folder? + */ + if (OPENBASEDIR_CHECKPATH(fullpath)) { + efree(file_dirname_fullpath); + efree(file_basename); + return 0; + } + zf = zip_fopen(za, file, 0); if (zf == NULL) { efree(fullpath); @@ -609,6 +624,9 @@ static PHP_FUNCTION(zip_open) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &filename_zval) == FAILURE) { return; } + if (OPENBASEDIR_CHECKPATH(filename)) { + RETURN_FALSE; + } if (FAILURE == php_stream_path_param_encode(filename_zval, &filename, &filename_len, REPORT_ERRORS, FG(default_context))) { RETURN_FALSE; diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index cbfc9b9502..f194151941 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -30,6 +30,16 @@ extern zend_module_entry zip_module_entry; #include "lib/zip.h" +/* {{{ OPENBASEDIR_CHECKPATH(filename) */ +#if (PHP_MAJOR_VERSION < 6) +#define OPENBASEDIR_CHECKPATH(filename) \ + (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC) +#else +#define OPENBASEDIR_CHECKPATH(filename) \ + php_check_open_basedir(filename TSRMLS_CC) +#endif +/* }}} */ + typedef struct _ze_zip_rsrc { struct zip *za; int index_current; diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index c36df3e4c0..1f305509ea 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -12,6 +12,7 @@ #include "ext/standard/file.h" #include "ext/standard/php_string.h" #include "fopen_wrappers.h" +#include "php_zip.h" #include "ext/standard/url.h" @@ -112,6 +113,10 @@ php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_D } if (filename) { + if (OPENBASEDIR_CHECKPATH(filename)) { + return NULL; + } + /* duplicate to make the stream za independent (esp. for MSHUTDOWN) */ stream_za = zip_open(filename, ZIP_CREATE, &err); if (!stream_za) { @@ -189,6 +194,11 @@ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, php_basename(path, path_len - fragment_len, NULL, 0, &file_basename, &file_basename_len TSRMLS_CC); fragment++; + if (OPENBASEDIR_CHECKPATH(file_dirname)) { + efree(file_basename); + return NULL; + } + za = zip_open(file_dirname, ZIP_CREATE, &err); if (za) { zf = zip_fopen(za, fragment, 0); |