summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-03-01 23:11:42 -0800
committerStanislav Malyshev <stas@php.net>2016-03-01 23:11:42 -0800
commit2e874114a235e3ecabe044d2b8768e693f3cec5a (patch)
treef4385e73070350c26feaac314bcd297cceffebbd
parent289e492251bcdafcd56439b758bc991a8d333b13 (diff)
parent6823ee923de6e9cbd6ced8e3f87fc83a2c3bc444 (diff)
downloadphp-git-2e874114a235e3ecabe044d2b8768e693f3cec5a.tar.gz
Merge branch 'PHP-7.0'
* PHP-7.0: (25 commits) Update NEWS update NEWS fix test file Fix version update NEWS Update NEWS Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request() Fix bug #71637: Multiple Heap Overflow due to integer overflows extend check for add_flag Fixed another segfault with file_cache_only now set version fix nmake clean in phpize mode Fixed segfault with file_cache_only Fixed possible crash at PCRE on MSHUTDOWN Fixed more synchronisation issues during SHM reload Set proper type flags (REFCOUNTED and COPYABLE) according to interned or regular string sync with improvements in NEWS Fixed process synchronisation problem, that may cause crashes after opcache restart Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request() Fix bug #71637: Multiple Heap Overflow due to integer overflows ...
-rw-r--r--ext/filter/sanitizing_filters.c2
-rwxr-xr-xext/phar/tests/bug70433.zipbin264 -> 269 bytes
-rw-r--r--ext/phar/tests/bug71488.phpt1
-rw-r--r--ext/phar/tests/bug71498.phpt17
-rw-r--r--ext/phar/tests/bug71498.zipbin0 -> 65677 bytes
-rw-r--r--ext/phar/zip.c2
-rw-r--r--ext/soap/php_http.c2
-rw-r--r--ext/soap/tests/bug71610.phpt15
-rw-r--r--ext/standard/string.c2
-rw-r--r--ext/wddx/tests/bug71587.phpt43
-rw-r--r--ext/wddx/wddx.c17
-rw-r--r--ext/xml/xml.c2
-rw-r--r--sapi/cli/php_cli_server.c2
13 files changed, 97 insertions, 8 deletions
diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c
index ff27bdb1be..0b11ecfc2a 100644
--- a/ext/filter/sanitizing_filters.c
+++ b/ext/filter/sanitizing_filters.c
@@ -87,7 +87,7 @@ static void php_filter_encode_url(zval *value, const unsigned char* chars, const
memset(tmp, 1, 32);
}
*/
- str = zend_string_alloc(3 * Z_STRLEN_P(value), 0);
+ str = zend_string_safe_alloc(Z_STRLEN_P(value), 3, 0, 0);
p = (unsigned char *) ZSTR_VAL(str);
s = (unsigned char *) Z_STRVAL_P(value);
e = s + Z_STRLEN_P(value);
diff --git a/ext/phar/tests/bug70433.zip b/ext/phar/tests/bug70433.zip
index 3994a30a8e..232a2210f5 100755
--- a/ext/phar/tests/bug70433.zip
+++ b/ext/phar/tests/bug70433.zip
Binary files differ
diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt
index 05fdd8f481..22d2bf098f 100644
--- a/ext/phar/tests/bug71488.phpt
+++ b/ext/phar/tests/bug71488.phpt
@@ -7,6 +7,7 @@ Phar: bug #71488: Stack overflow when decompressing tar archives
$p = new PharData(__DIR__."/bug71488.tar");
$newp = $p->decompress("test");
?>
+
DONE
--CLEAN--
<?php
diff --git a/ext/phar/tests/bug71498.phpt b/ext/phar/tests/bug71498.phpt
new file mode 100644
index 0000000000..de6283c8dc
--- /dev/null
+++ b/ext/phar/tests/bug71498.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Phar: bug #71498: Out-of-Bound Read in phar_parse_zipfile()
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+try {
+$p = new PharData(__DIR__."/bug71498.zip");
+} catch(UnexpectedValueException $e) {
+ echo $e->getMessage();
+}
+?>
+
+DONE
+--EXPECTF--
+phar error: end of central directory not found in zip-based phar "%s/bug71498.zip"
+DONE \ No newline at end of file
diff --git a/ext/phar/tests/bug71498.zip b/ext/phar/tests/bug71498.zip
new file mode 100644
index 0000000000..ae78dd871e
--- /dev/null
+++ b/ext/phar/tests/bug71498.zip
Binary files differ
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
index 4994dd0e04..30c52c0479 100644
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -199,7 +199,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
}
while ((p=(char *) memchr(p + 1, 'P', (size_t) (size - (p + 1 - buf)))) != NULL) {
- if (!memcmp(p + 1, "K\5\6", 3)) {
+ if ((p - buf) + sizeof(locator) <= size && !memcmp(p + 1, "K\5\6", 3)) {
memcpy((void *)&locator, (void *) p, sizeof(locator));
if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) {
/* split archives not handled */
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index 2baa0fa3ff..a2d0b6207d 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -833,8 +833,10 @@ try_again:
Z_TYPE_P(value) == IS_STRING) {
zval *tmp;
if (((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 1)) == NULL ||
+ Z_TYPE_P(tmp) != IS_STRING ||
strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) &&
((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 2)) == NULL ||
+ Z_TYPE_P(tmp) != IS_STRING ||
in_domain(phpurl->host,Z_STRVAL_P(tmp))) &&
(use_ssl || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL)) {
smart_str_append(&soap_headers, key);
diff --git a/ext/soap/tests/bug71610.phpt b/ext/soap/tests/bug71610.phpt
new file mode 100644
index 0000000000..4f1c7162ff
--- /dev/null
+++ b/ext/soap/tests/bug71610.phpt
@@ -0,0 +1,15 @@
+--TEST--
+SOAP Bug #71610 - Type Confusion Vulnerability - SOAP / make_http_soap_request()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$exploit = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"a";s:8:"location";s:19:"http://testuri.org/";s:8:"_cookies";a:1:{s:8:"manhluat";a:3:{i:0;s:0:"";i:1;N;i:2;N;}}}}');
+try {
+$exploit->blahblah();
+} catch(SoapFault $e) {
+ echo $e->getMessage()."\n";
+}
+?>
+--EXPECT--
+looks like we got no XML document
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 82aa97e8cd..4377830986 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -5370,7 +5370,7 @@ PHP_FUNCTION(str_pad)
return;
}
- result = zend_string_alloc(ZSTR_LEN(input) + num_pad_chars, 0);
+ result = zend_string_safe_alloc(ZSTR_LEN(input), 1, num_pad_chars, 0);
ZSTR_LEN(result) = 0;
/* We need to figure out the left/right padding lengths. */
diff --git a/ext/wddx/tests/bug71587.phpt b/ext/wddx/tests/bug71587.phpt
new file mode 100644
index 0000000000..3fdfc35c16
--- /dev/null
+++ b/ext/wddx/tests/bug71587.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #71587 (Use-After-Free / Double-Free in WDDX Deserialize)
+--SKIPIF--
+<?php
+if (!extension_loaded("wddx")) print "skip";
+?>
+--FILE--
+<?php
+
+$xml = <<<EOF
+<?xml version='1.0' ?>
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
+<wddxPacket version='1.0'>
+ <array>
+ <var name='ML'></var>
+ <string>manhluat</string>
+ <var name='ML2'></var>
+ <boolean value='a'/>
+ <boolean value='true'/>
+ </array>
+</wddxPacket>
+EOF;
+
+$wddx = wddx_deserialize($xml);
+var_dump($wddx);
+// Print mem leak
+foreach($wddx as $k=>$v)
+ printf("Key: %s\nValue: %s\n",bin2hex($k),bin2hex($v));
+
+?>
+DONE
+--EXPECTF--
+array(2) {
+ [0]=>
+ string(8) "manhluat"
+ [1]=>
+ bool(true)
+}
+Key: 30
+Value: 6d616e686c756174
+Key: 31
+Value: 31
+DONE
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index ca7b711682..539ed57662 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -877,6 +877,16 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
!strcmp((char *)name, EL_DATETIME)) {
wddx_stack_top(stack, (void**)&ent1);
+ if (!ent1->data) {
+ if (stack->top > 1) {
+ stack->top--;
+ } else {
+ stack->done = 1;
+ }
+ efree(ent1);
+ return;
+ }
+
if (!strcmp((char *)name, EL_BINARY)) {
zend_string *new_str = php_base64_decode(
(unsigned char *)Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
@@ -964,6 +974,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
}
} else if (!strcmp((char *)name, EL_VAR) && stack->varname) {
efree(stack->varname);
+ stack->varname = NULL;
} else if (!strcmp((char *)name, EL_FIELD)) {
st_entry *ent;
wddx_stack_top(stack, (void **)&ent);
@@ -1005,11 +1016,11 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
} else if (!strcmp((char *)s, "false")) {
Z_LVAL(ent->data) = 0;
} else {
- stack->top--;
zval_ptr_dtor(&ent->data);
- if (ent->varname)
+ if (ent->varname) {
efree(ent->varname);
- efree(ent);
+ }
+ ent->data = NULL;
}
break;
diff --git a/ext/xml/xml.c b/ext/xml/xml.c
index b832732f0d..49b72a0acc 100644
--- a/ext/xml/xml.c
+++ b/ext/xml/xml.c
@@ -581,7 +581,7 @@ PHP_XML_API zend_string *xml_utf8_encode(const char *s, size_t len, const XML_Ch
}
/* This is the theoretical max (will never get beyond len * 2 as long
* as we are converting from single-byte characters, though) */
- str = zend_string_alloc(len * 4, 0);
+ str = zend_string_safe_alloc(len, 4, 0, 0);
ZSTR_LEN(str) = 0;
while (pos > 0) {
c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s);
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index ac41c44def..f94ac74741 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -1964,7 +1964,7 @@ static int php_cli_server_begin_send_static(php_cli_server *server, php_cli_serv
if (client->request.path_translated &&
('.' == client->request.path_translated[client->request.path_translated_len-1] ||
' ' == client->request.path_translated[client->request.path_translated_len-1])) {
- return php_cli_server_send_error_page(server, client, 500);
+ return php_cli_server_send_error_page(server, client, 500 TSRMLS_CC);
}
#endif