[Pkg-php-commits] r1223 - in php5/trunk/debian: . patches

Sean Finney seanius at alioth.debian.org
Sun Jan 18 23:36:20 UTC 2009


tags 507857 pending
thanks

Author: seanius
Date: 2009-01-18 23:36:19 +0000 (Sun, 18 Jan 2009)
New Revision: 1223

Added:
   php5/trunk/debian/patches/CVE-2008-5658.patch
Modified:
   php5/trunk/debian/changelog
   php5/trunk/debian/patches/series
Log:
initial attempt at backporting the zipfile fix

Modified: php5/trunk/debian/changelog
===================================================================
--- php5/trunk/debian/changelog	2009-01-18 19:25:33 UTC (rev 1222)
+++ php5/trunk/debian/changelog	2009-01-18 23:36:19 UTC (rev 1223)
@@ -8,6 +8,9 @@
   * Security related fixes:
     - php: inifile handler for the dba functions can be used to truncate a file
       Patch: dba-inifile-truncation.patch (closes: #507101).
+    - CVE-2008-5658.patch: ZipArchive::extractTo directory traversal
+      Patch: CVE-2008-5658.patch (closes: #507857).
+      THIS PATCH IS NOT YET TESTED
 
   [ Raphael Geissert ]
   * Picked up some patches from Gentoo (most included in PHP 5.2.7 and later):

Added: php5/trunk/debian/patches/CVE-2008-5658.patch
===================================================================
--- php5/trunk/debian/patches/CVE-2008-5658.patch	                        (rev 0)
+++ php5/trunk/debian/patches/CVE-2008-5658.patch	2009-01-18 23:36:19 UTC (rev 1223)
@@ -0,0 +1,166 @@
+--- php5-5.2.6.dfsg.1.orig/ext/zip/php_zip.c
++++ php5-5.2.6.dfsg.1/ext/zip/php_zip.c
+@@ -82,6 +82,46 @@ static int le_zip_entry;
+ 
+ /* }}} */
+ 
++/* Flatten a path by creating a relative path (to .) */
++static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */
++{
++	char *path_begin = path;
++	int prev_is_slash = 0;
++	char *e = path + path_len - 1;
++	size_t pos = path_len - 1;
++	size_t i;
++
++	if (IS_SLASH(path[0])) {
++		return path + 1;
++	}
++
++	if (path_len < 1 || path == NULL) {
++		return NULL;
++	}
++
++	i = path_len;
++
++	while (1) {
++		while (i > 0 && !IS_SLASH(path[i])) {
++			i--;
++		}
++
++		if (!i) {
++			return path;
++		}
++
++		if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
++			/* i is the position of . or :, add 1 for / */
++			path_begin = path + i + 1;
++			break;
++		}
++		i--;
++	}
++
++	return path_begin;
++}
++/* }}} */
++
+ /* {{{ php_zip_extract_file */
+ /* TODO: Simplify it */
+ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len TSRMLS_DC)
+@@ -103,57 +143,78 @@ static int php_zip_extract_file(struct z
+ 	char *file_basename;
+ 	size_t file_basename_len;
+ 	int is_dir_only = 0;
++	char *path_cleaned;
++	size_t path_cleaned_len;
++	cwd_state new_state;
++
++	new_state.cwd = (char*)malloc(1);
++	new_state.cwd[0] = '\0';
++	new_state.cwd_length = 0;
+ 
+-	if (file_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
++	/* Clean/normlize the path and then transform any path (absolute or relative)
++		 to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
++	 */
++	virtual_file_ex(&new_state, file, NULL, CWD_EXPAND);
++	path_cleaned =  php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
++	path_cleaned_len = strlen(path_cleaned);
++
++	if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
+ 		return 0;
+ 	}
+ 
+-	if (file_len > 1 && file[file_len - 1] == '/') {
++	/* it is a directory only, see #40228 */
++	if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
+ 		len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file);
+ 		is_dir_only = 1;
+ 	} else {
+-		memcpy(file_dirname, file, file_len);
+-		dir_len = php_dirname(file_dirname, file_len);
++		memcpy(file_dirname, path_cleaned, path_cleaned_len);
++		dir_len = php_dirname(file_dirname, path_cleaned_len);
+ 
+-		if (dir_len > 0) {
+-			len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
+-		} else {
++		if (dir_len <= 0 || (dir_len == 1 && file_dirname[0] == '.')) {
+ 			len = spprintf(&file_dirname_fullpath, 0, "%s", dest);
++		} else {
++			len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
+ 		}
+ 
+-		php_basename(file, file_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC);
++		php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC);
+ 
+ 		if (OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
+ 			efree(file_dirname_fullpath);
+ 			efree(file_basename);
++			free(new_state.cwd);
+ 			return 0;
+ 		}
+ 	}
+ 
+ 	/* let see if the path already exists */
+ 	if (php_stream_stat_path(file_dirname_fullpath, &ssb) < 0) {
+-		ret = php_stream_mkdir(file_dirname_fullpath, 0777,  PHP_STREAM_MKDIR_RECURSIVE, NULL);
++
++		ret = php_stream_mkdir(file_dirname_fullpath, 0777,  PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL);
+ 		if (!ret) {
+ 			efree(file_dirname_fullpath);
++			if (!is_dir_only) {
+ 			efree(file_basename);
++				free(new_state.cwd);
++			}
+ 			return 0;
+ 		}
+ 	}
+ 
+ 	/* it is a standalone directory, job done */
+-	if (file[file_len - 1] == '/') {
++	if (is_dir_only) {
+ 		efree(file_dirname_fullpath);
+-		if (!is_dir_only) {
+-			efree(file_basename);
+-		}
++		free(new_state.cwd);
+ 		return 1;
+ 	}
+ 
+-	len = spprintf(&fullpath, 0, "%s/%s/%s", dest, file_dirname, file_basename);
++	len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, file_basename);
+ 	if (!len) {
+ 		efree(file_dirname_fullpath);
+ 		efree(file_basename);
++		free(new_state.cwd);
+ 		return 0;
++	} else if (len > MAXPATHLEN) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
+ 	}
+ 
+ 	/* check again the full path, not sure if it
+@@ -164,6 +225,7 @@ static int php_zip_extract_file(struct z
+ 		efree(fullpath);
+ 		efree(file_dirname_fullpath);
+ 		efree(file_basename);
++		free(new_state.cwd);
+ 		return 0;
+ 	}
+ 
+@@ -172,6 +234,7 @@ static int php_zip_extract_file(struct z
+ 		efree(fullpath);
+ 		efree(file_dirname_fullpath);
+ 		efree(file_basename);
++		free(new_state.cwd);
+ 		return 0;
+ 	}
+ 
+@@ -186,6 +249,7 @@ static int php_zip_extract_file(struct z
+ 	efree(fullpath);
+ 	efree(file_basename);
+ 	efree(file_dirname_fullpath);
++	free(new_state.cwd);
+ 
+ 	if (n<0) {
+ 		return 0;

Modified: php5/trunk/debian/patches/series
===================================================================
--- php5/trunk/debian/patches/series	2009-01-18 19:25:33 UTC (rev 1222)
+++ php5/trunk/debian/patches/series	2009-01-18 23:36:19 UTC (rev 1223)
@@ -51,3 +51,4 @@
 gentoo/007_dom-setAttributeNode-crash.patch
 gentoo/006_PDORow-crash.patch
 gentoo/005_stream_context_set_params-crash.patch
+CVE-2008-5658.patch




More information about the Pkg-php-commits mailing list