php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72541 size_t overflow lead to heap corruption
Submitted: 2016-07-04 07:42 UTC Modified: 2016-08-01 02:43 UTC
From: minhrau dot vc dot 365 at gmail dot com Assigned: stas (profile)
Status: Closed Package: cURL related
PHP Version: 7.0.8 OS: ALL
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: minhrau dot vc dot 365 at gmail dot com
New email:
PHP Version: OS:

 

 [2016-07-04 07:42 UTC] minhrau dot vc dot 365 at gmail dot com
Description:
------------
In "curl_unescape" function, if we provide the string with length 0xffffffff, 

PHP_FUNCTION(curl_unescape)
{
	char       *str = NULL, *out = NULL;
	size_t     str_len = 0;
	int        out_len;
	zval       *zid;
	php_curl   *ch;

	...

	if ((out = curl_easy_unescape(ch->cp, str, str_len, &out_len))) { //<- crashes here
		RETVAL_STRINGL(out, out_len);
		curl_free(out);
	} 
	...
}

Take a loot at curl_easy_unescape in libcurl:

char *curl_easy_unescape(struct Curl_easy *data, const char *string,
                         int length, int *olen)
{
...
  CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
                                FALSE);
...
}

and Curl_urldecode:

CURLcode Curl_urldecode(struct Curl_easy *data,
                        const char *string, size_t length,
                        char **ostring, size_t *olen,
                        bool reject_ctrl)
{
  size_t alloc = (length?length:strlen(string))+1; //<- the 0xffffffff length of string above will cause value of alloc = 0
  ...

  while(--alloc > 0) { //--alloc = 0xffffffff for the first check, it will loop for 0xffffffff times
  ...

    ns[strindex++] = in; //heep overflow here
    string++;
  }
  ...
}

Test script:
---------------
<?php

ini_set('memory_limit', -1);
$str = str_repeat("A", 0xffffffff);
// Create a curl handle
$ch = curl_init('http://example.com/redirect.php');
curl_unescape($ch, $str);
?>


Expected result:
----------------
No crash

Actual result:
--------------
Some backtrace:
(gdb) bt
#0  0x00007ffff6a97218 in ?? () from /usr/lib/libcurl.so.4
#1  0x00007ffff6a97316 in curl_easy_unescape () from /usr/lib/libcurl.so.4
#2  0x00000000005fd2da in zif_curl_unescape (execute_data=0x7ffff3a15100, return_value=0x7fffffffabe0) at /php-src/ext/curl/interface.c:3601
#3  0x00000000008f8faa in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /php-src/Zend/zend_vm_execute.h:631
#4  0x00000000008f8881 in execute_ex (ex=0x7ffff3a15030) at /php-src/Zend/zend_vm_execute.h:428
#5  0x00000000008f8991 in zend_execute (op_array=0x7ffff3a7e000, return_value=0x0) at /php-src/Zend/zend_vm_execute.h:473
#6  0x000000000089a765 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /php-src/Zend/zend.c:1441
#7  0x000000000080a27c in php_execute_script (primary_file=0x7fffffffe280) at /php-src/main/main.c:2515
#8  0x000000000097573b in do_cli (argc=2, argv=0x115fd50) at /php-src/sapi/cli/php_cli.c:993
#9  0x0000000000976705 in main (argc=2, argv=0x115fd50) at /php-src/sapi/cli/php_cli.c:1381

Some debug info:
(gdb) x/i $rip
=> 0x7ffff6a97218:	mov    BYTE PTR [r14+r15*1-0x1],al
(gdb) i r $r14 $r15
r14            0x12a3990	19544464
r15            0x5	5

Crash:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff54f1218 in ?? () from /usr/lib/libcurl.so.4
(gdb) i r $r14 $r15
r14            0x12a39f0	19544560
r15            0x35611	218641
      
(gdb) i proc mappings 
process 31102
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0xe93000   0xa93000        0x0 /php-src/sapi/cli/php
           0x1092000          0x113c000    0xaa000   0xa92000 /php-src/sapi/cli/php
           0x113c000          0x12d9000   0x19d000        0x0 [heap]


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-13 06:05 UTC] stas@php.net
-PHP Version: 7.1Git-2016-07-04 (Git) +PHP Version: 7.0.8
 [2016-07-13 06:05 UTC] stas@php.net
Fix in security repo as 2ca8d85dd4ac6d5f8c046f339f9636e3099b0f08 and https://gist.github.com/6533bffdda9cabb14319103fa1c3aefb

Should be applied from 7.0 up. Don't think 5.x is affected.
 [2016-07-13 06:06 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-07-14 02:01 UTC] minhrau dot vc dot 365 at gmail dot com
The patch look good.
 [2016-07-18 08:46 UTC] ab@php.net
For such range checks macros from Zend/zend_range_checks.h could be used. They're additionally wrapped with UNEXPECTED(), but could also be optimized away completely if not relevant for some platform.

Thanks.
 [2016-07-19 08:55 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2ca8d85dd4ac6d5f8c046f339f9636e3099b0f08
Log: Fix bug #72541 - size_t overflow lead to heap corruption
 [2016-07-19 08:55 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-07-19 17:59 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=159403f7952a8616bfc6858c60f5314599a36652
Log: Fix bug #72541 - size_t overflow lead to heap corruption
 [2016-07-20 11:30 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2ca8d85dd4ac6d5f8c046f339f9636e3099b0f08
Log: Fix bug #72541 - size_t overflow lead to heap corruption
 [2016-08-01 02:43 UTC] minhrau dot vc dot 365 at gmail dot com
Hi,

Can I request CVE for this report?

I tried to reach CVE assign for opensource here http://iwantacve.org, but seem they inactive now.

Thanks.
 [2016-10-17 10:11 UTC] bwoebi@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2ca8d85dd4ac6d5f8c046f339f9636e3099b0f08
Log: Fix bug #72541 - size_t overflow lead to heap corruption
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 27 16:01:27 2024 UTC