summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2020-01-20 22:47:01 -0800
committerDerick Rethans <github@derickrethans.nl>2020-01-21 10:10:02 +0000
commitbea47b794f93dedb9e30f27586ece1fc8b6bca27 (patch)
tree049a091935481a3208fe7e4eb5b8122bcf7dabf4
parentc497becad41376c7358d75e3b38eb472a434549e (diff)
downloadphp-git-bea47b794f93dedb9e30f27586ece1fc8b6bca27.tar.gz
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Update NEWS Fix bug #79037 (global buffer-overflow in `mbfl_filt_conv_big5_wchar`) Fix #79099: OOB read in php_strip_tags_ex Fix #79091: heap use-after-free in session_create_id()
-rw-r--r--ext/mbstring/libmbfl/filters/mbfilter_big5.c4
-rw-r--r--ext/mbstring/tests/bug79037.phpt10
-rw-r--r--ext/session/session.c1
-rw-r--r--ext/session/tests/bug79091.phpt67
-rw-r--r--ext/standard/string.c6
-rw-r--r--ext/standard/tests/file/bug79099.phpt32
6 files changed, 115 insertions, 5 deletions
diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c
index 0fc57d62b1..6c071e0e99 100644
--- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c
+++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c
@@ -145,10 +145,10 @@ static unsigned short cp950_pua_tbl[][4] = {
static inline int is_in_cp950_pua(int c1, int c) {
if ((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) ||
(c1 >= 0x81 && c1 <= 0x8d) || (c1 >= 0xc7 && c1 <= 0xc8)) {
- return (c > 0x39 && c < 0x7f) || (c > 0xa0 && c < 0xff);
+ return (c >=0x40 && c <= 0x7e) || (c >= 0xa1 && c <= 0xfe);
}
if (c1 == 0xc6) {
- return c > 0xa0 && c < 0xff;
+ return c >= 0xa1 && c <= 0xfe;
}
return 0;
}
diff --git a/ext/mbstring/tests/bug79037.phpt b/ext/mbstring/tests/bug79037.phpt
new file mode 100644
index 0000000000..94ff01a4a1
--- /dev/null
+++ b/ext/mbstring/tests/bug79037.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Bug #79037: global buffer-overflow in `mbfl_filt_conv_big5_wchar`
+--FILE--
+<?php
+
+var_dump(mb_convert_encoding("\x81\x3a", "UTF-8", "CP950"));
+
+?>
+--EXPECT--
+string(1) "?"
diff --git a/ext/session/session.c b/ext/session/session.c
index 671968e8da..7c7e4841e4 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -2296,6 +2296,7 @@ static PHP_FUNCTION(session_create_id)
/* Detect collision and retry */
if (PS(mod)->s_validate_sid(&PS(mod_data), new_id) == FAILURE) {
zend_string_release_ex(new_id, 0);
+ new_id = NULL;
continue;
}
break;
diff --git a/ext/session/tests/bug79091.phpt b/ext/session/tests/bug79091.phpt
new file mode 100644
index 0000000000..1d14427159
--- /dev/null
+++ b/ext/session/tests/bug79091.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Bug #79091 (heap use-after-free in session_create_id())
+--SKIPIF--
+<?php
+if (!extension_loaded('session')) die('skip session extension not available');
+?>
+--FILE--
+<?php
+class MySessionHandler implements SessionHandlerInterface, SessionIdInterface, SessionUpdateTimestampHandlerInterface
+{
+ public function close()
+ {
+ return true;
+ }
+
+ public function destroy($session_id)
+ {
+ return true;
+ }
+
+ public function gc($maxlifetime)
+ {
+ return true;
+ }
+
+ public function open($save_path, $session_name)
+ {
+ return true;
+ }
+
+ public function read($session_id)
+ {
+ return '';
+ }
+
+ public function write($session_id, $session_data)
+ {
+ return true;
+ }
+
+ public function create_sid()
+ {
+ return uniqid();
+ }
+
+ public function updateTimestamp($key, $val)
+ {
+ return true;
+ }
+
+ public function validateId($key)
+ {
+ return false;
+ }
+}
+
+ob_start();
+var_dump(session_set_save_handler(new MySessionHandler()));
+var_dump(session_start());
+ob_flush();
+session_create_id();
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+
+Warning: session_create_id(): Failed to create new ID in %s on line %d
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 50934e1b50..934936ba94 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -5278,7 +5278,7 @@ state_1:
}
lc = '>';
- if (is_xml && *(p -1) == '-') {
+ if (is_xml && p >= buf + 1 && *(p -1) == '-') {
break;
}
in_q = state = is_xml = 0;
@@ -5310,7 +5310,7 @@ state_1:
goto reg_char_1;
case '!':
/* JavaScript & Other HTML scripting languages */
- if (*(p-1) == '<') {
+ if (p >= buf + 1 && *(p-1) == '<') {
state = 3;
lc = c;
p++;
@@ -5320,7 +5320,7 @@ state_1:
}
break;
case '?':
- if (*(p-1) == '<') {
+ if (p >= buf + 1 && *(p-1) == '<') {
br=0;
state = 2;
p++;
diff --git a/ext/standard/tests/file/bug79099.phpt b/ext/standard/tests/file/bug79099.phpt
new file mode 100644
index 0000000000..a1f2a3355f
--- /dev/null
+++ b/ext/standard/tests/file/bug79099.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #79099 (OOB read in php_strip_tags_ex)
+--FILE--
+<?php
+$stream = fopen('php://memory', 'w+');
+fputs($stream, "<?\n\"\n");
+rewind($stream);
+var_dump(@fgetss($stream));
+var_dump(@fgetss($stream));
+fclose($stream);
+
+$stream = fopen('php://memory', 'w+');
+fputs($stream, "<\0\n!\n");
+rewind($stream);
+var_dump(@fgetss($stream));
+var_dump(@fgetss($stream));
+fclose($stream);
+
+$stream = fopen('php://memory', 'w+');
+fputs($stream, "<\0\n?\n");
+rewind($stream);
+var_dump(@fgetss($stream));
+var_dump(@fgetss($stream));
+fclose($stream);
+?>
+--EXPECT--
+string(0) ""
+string(0) ""
+string(0) ""
+string(0) ""
+string(0) ""
+string(0) ""