php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72552 In correct casting from size_t to int lead to heap overflow in mdecrypt_generic
Submitted: 2016-07-06 07:59 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
 [2016-07-06 07:59 UTC] minhrau dot vc dot 365 at gmail dot com
Description:
------------
The same problem in mcrypt_generic, function mdecrypt_generic has this vuln:

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

(1) -> 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 = mdecrypt_generic($td, $str);

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

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

Patch:
------------
diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c
index 656a77c..2039fd6 100644
--- a/ext/mcrypt/mcrypt.c
+++ b/ext/mcrypt/mcrypt.c
@@ -695,7 +699,11 @@ PHP_FUNCTION(mdecrypt_generic)
                memset(data_s, 0, data_size);
                memcpy(data_s, data, data_len);
        } else { /* It's not a block algorithm */
-               data_size = (int)data_len;
+               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_s = emalloc(data_size + 1);
                memset(data_s, 0, data_size);
                memcpy(data_s, data, data_len);

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 8, zif_mdecrypt_generic (execute_data=<optimized out>, return_value=0x7ffff5c141c0) at /php-src/ext/mcrypt/mcrypt.c:703
703			data_s = emalloc(data_size + 1);
(gdb) p data_size
$54 = <optimized out>
(gdb) p data_len
$55 = 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  0x000000000058347d in zif_mdecrypt_generic (execute_data=<optimized out>, return_value=0x7ffff5c141c0) at /php-src/ext/mcrypt/mcrypt.c:705
#2  0x00000000007341c6 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /php-src/Zend/zend_vm_execute.h:678
#3  0x0000000000723bdb in execute_ex (ex=<optimized out>) at /php-src/Zend/zend_vm_execute.h:428
#4  0x000000000077c098 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  0x00000000006dcfa5 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  0x000000000067ea50 in php_execute_script (primary_file=primary_file@entry=0x7fffffffd230) at /php-src/main/main.c:2515
#7  0x000000000077e33a 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:18 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:18 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 09:01 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-07-19 09:01 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [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:30 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: Tue Mar 19 04:01:31 2024 UTC