php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73761 Integer overflow in str_repeat()
Submitted: 2016-12-16 15:48 UTC Modified: 2016-12-19 15:35 UTC
From: whitehat002 at hotmail dot com Assigned:
Status: Not a bug Package: Strings related
PHP Version: 7.0.14 OS: windows
Private report: No CVE-ID: None
 [2016-12-16 15:48 UTC] whitehat002 at hotmail dot com
Description:
------------
Discovered by yaozhihua of DPtech
In all versions of php 7, I have tested it which can cause integer overflow.

the source code in /ext/standrd/string.c:4908

PHP_FUNCTION(str_repeat)
{
	zend_string		*input_str;		
	zend_long 		mult;	 //here the tyep is int		
	zend_string	*result;		
	size_t		result_len;		

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sl", &input_str, &mult) == FAILURE) {
		return;
	}

	if (mult < 0) {
		php_error_docref(NULL, E_WARNING, "Second argument has to be greater than or equal to 0");
		return;
	}

	/* Don't waste our time if it's empty */
	/* ... or if the multiplier is zero */
	if (ZSTR_LEN(input_str) == 0 || mult == 0)
		RETURN_EMPTY_STRING();

	/* Initialize the result string */
	result = zend_string_safe_alloc(ZSTR_LEN(input_str), mult, 0, 0);//integer overflow
	result_len = ZSTR_LEN(input_str) * mult;

	/* Heavy optimization for situations where input string is 1 byte long */
	if (ZSTR_LEN(input_str) == 1) {
		memset(ZSTR_VAL(result), *ZSTR_VAL(input_str), mult);
	} else {
		char *s, *e, *ee;
		ptrdiff_t l=0;
		memcpy(ZSTR_VAL(result), ZSTR_VAL(input_str), ZSTR_LEN(input_str));
		s = ZSTR_VAL(result);
		e = ZSTR_VAL(result) + ZSTR_LEN(input_str);
		ee = ZSTR_VAL(result) + result_len;

		while (e<ee) {
			l = (e-s) < (ee-e) ? (e-s) : (ee-e);
			memmove(e, s, l);
			e += l;
		}
	}

	ZSTR_VAL(result)[result_len] = '\0';

	RETURN_NEW_STR(result);
}

And I have some questions.Why does it not cause heap overflow?for the record,I am a novice in the field of vulnerability.

Test script:
---------------
<?php
ini_set('memory_limit',-1);
$s=str_repeat('\x90\x90\x90\x90\x90\x90AA',0xffffffff/26);

?>

Expected result:
----------------
no crash

Actual result:
--------------
Fatal error: Possible integer overflow in memory allocation (26 * 165191049 +24
) in C:\Users\yaozhihua\Desktop\php-7.0.14-Win32-VC14-x86\test.php on line 3

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-18 01:27 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2016-12-18 01:27 UTC] ab@php.net
Thanks for the report. There is no further processing after the fatal error, the process just exits - thus there's no crash. Further details will probably lead you to Zend memory manager in Zend/zend_alloc.c. Or, if it's indeed crashing on your side, please post the backtrace or share a memory dump.

Thanks.
 [2016-12-18 02:54 UTC] whitehat002 at hotmail dot com
-Status: Feedback +Status: Open
 [2016-12-18 02:54 UTC] whitehat002 at hotmail dot com
Thanks,I got it.
 [2016-12-18 02:56 UTC] whitehat002 at hotmail dot com
What kind of vulnerability can assign CVE?
 [2016-12-19 15:35 UTC] ab@php.net
-Status: Open +Status: Not a bug
 [2016-12-19 15:35 UTC] ab@php.net
Please read https://wiki.php.net/security

Thanks.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Dec 14 13:01:24 2019 UTC