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
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: whitehat002 at hotmail dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 11:01:30 2024 UTC