Sec Bug->Bug #73136 [Opn->Nab]: NULL pointer dereference in mb_parse_str
| From: | stas@php.net | Date: | Mon, 26 Sep 2016 03:06:03 +0000 |
| Subject: | Sec Bug->Bug #73136 [Opn->Nab]: NULL pointer dereference in mb_parse_str | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-204260@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73136&edit=1
ID: 73136
Updated by: stas@php.net
Reported by: minhrau dot vc dot 365 at gmail dot com
Summary: NULL pointer dereference in mb_parse_str
-Status: Open
+Status: Not a bug
-Type: Security
+Type: Bug
Package: mbstring related
Operating System: ALL
PHP Version: 7.0.11
Block user comment: N
Private report: Y
New Comment:
Please next time report all non-standard settings you used.
Setting USE_ZEND_ALLOC=0 overrides normal memory management, and in this case if you're out of
memory you'd get segfault.
Previous Comments:
------------------------------------------------------------------------
[2016-09-26 03:03:07] minhrau dot vc dot 365 at gmail dot com
I tried to add this line below into my testcase, its output is 1000. But I didn't get the
"Warning: mb_parse_str(): Input variables exceeded 1000". But this is a warning, script
will continue running?
echo ini_get("max_input_vars");
And must export this: export USE_ZEND_ALLOC=0 to use normal alloc.
------------------------------------------------------------------------
[2016-09-26 02:50:46] stas@php.net
The default for max_input_vars is 1000. Did you use any additional options? I still am unable to
reproduce any issue.
------------------------------------------------------------------------
[2016-09-26 01:47:45] minhrau dot vc dot 365 at gmail dot com
Could you check your php.ini?
In default configuration, the line max_input_vars had been comment out.
; max_input_vars = 1000
Regards.
------------------------------------------------------------------------
[2016-09-25 23:20:19] stas@php.net
Could not reproduce the issue. I get:
Warning: mb_parse_str(): Input variables exceeded 1000. To increase the limit change max_input_vars
in php.ini. in /Users/smalyshev/php-7.0/mamp/73136.php on line 7
------------------------------------------------------------------------
[2016-09-21 07:53:00] minhrau dot vc dot 365 at gmail dot com
Description:
------------
There are a NULL pointer dereference in mb_parse_str. If the num of elements is large, will be not
enough space for ecalloc function. So the ecalloc will fail and val_list will be null.
227 val_list = (char **)ecalloc(num, sizeof(char *));
After that, the reference to val_list will cause program to crash.
Test script:
---------------
<?php
ini_set('memory_limit', -1);
$str =
"email=kehaovista@qq.com&city=shanghai&job=Phper".str_repeat('&a',
0xffffffff/8);
mb_parse_str($str, $result);
?>
Expected result:
----------------
No Crash
Actual result:
--------------
Starting program: /home/minhrau/php-src/sapi/cli/php ~/phptestcase/testmb_parse_str.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Breakpoint 3, zend_parse_parameters (num_args=2, type_spec=0x10afdf5 "SS") at
/home/minhrau/php-src/Zend/zend_API.c:957
957 int flags = 0;
(gdb) c
Continuing.
Breakpoint 3, zend_parse_parameters (num_args=2, type_spec=0x10c1012 "Sl") at
/home/minhrau/php-src/Zend/zend_API.c:957
957 int flags = 0;
(gdb) c
Continuing.
Breakpoint 3, zend_parse_parameters (num_args=2, type_spec=0x107c02d "s|z/") at
/home/minhrau/php-src/Zend/zend_API.c:957
957 int flags = 0;
(gdb) c
Continuing.
Breakpoint 4, zif_mb_parse_str (execute_data=0x7ffff0284100, return_value=0x7fffffffa8d0) at
/home/minhrau/php-src/ext/mbstring/mbstring.c:2116
2116 if (track_vars_array != NULL) {
(gdb) c
Continuing.
Breakpoint 5, _php_mb_encoding_handler_ex (info=0x7fffffffa850, arg=0x1637a38, res=0x7fffb0283010
"email=kehaovista@qq.com&city=shanghai&job=Phper&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&a&"...)
at /home/minhrau/php-src/ext/mbstring/mb_gpc.c:227
227 val_list = (char **)ecalloc(num, sizeof(char *));
(gdb) p num
$5 = 1073741828
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x000000000070a257 in _php_mb_encoding_handler_ex (info=0x7fffffffa850, arg=0x1637a38,
res=0x7fffb0283010 "email") at /home/minhrau/php-src/ext/mbstring/mb_gpc.c:237
237 len_list[n] = php_url_decode(var, val-var);
(gdb) list
232 strtok_buf = NULL;
233 var = php_strtok_r(res, info->separator, &strtok_buf);
234 while (var) {
235 val = strchr(var, '=');
236 if (val) { /* have a value */
237 len_list[n] = php_url_decode(var, val-var);
238 val_list[n] = var;
239 n++;
240
241 *val++ = '\0';
(gdb)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73136&edit=1