summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Joye <pajoye@php.net>2007-03-14 11:22:13 +0000
committerPierre Joye <pajoye@php.net>2007-03-14 11:22:13 +0000
commit133c226f569c9e5bfc5290cbb360c01a0994a21f (patch)
tree3a510e9d5a89791a9296c88ea1fb9e34563b94a0
parente46b1b3747e85d219b74c7489d3a187ce08f3e24 (diff)
downloadphp-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.c18
-rw-r--r--ext/zip/php_zip.h10
-rw-r--r--ext/zip/zip_stream.c10
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);