Integer Overflow in Length of String-typed ZVAL

Sec Bug #72403 Integer Overflow in Length of String-typed ZVAL
Submitted: 2016-06-14 12:24 UTC Modified: 2016-06-27 19:23 UTC
From: taoguangchen at icloud dot com Assigned: stas (profile)
Status: Closed Package: *General Issues
PHP Version: 5.5.36 OS:
Private report: No CVE-ID: None

 [2016-06-14 12:24 UTC] taoguangchen at icloud dot com

Description:
------------
Some PHP5 functions can create strings with negative value lengths

rawurlencode
```
<?php

ini_set('memory_limit', -1);
$str = str_repeat("&", 0xffffffff/3);
$str = rawurlencode($str);
var_dump(strlen($str));

?>
```

bin2hex
```
<?php

ini_set('memory_limit', -1);
$str = str_repeat("A", 0xffffffff/4+1);
$str = bin2hex($str);
var_dump(strlen($str));

?>
```
implode (fixed in bug#72275)
```
<?php

ini_set('memory_limit', -1);
$str = str_repeat("A", 0xffffffff/4);
$arr = [$str, $str, $str, $str];
$str = implode($arr);
var_dump(strlen($str));

?>
```
quotemeta
```
<?php

ini_set('memory_limit', -1);
$str = str_repeat("$", 0xffffffff/4+1);
$str = quotemeta($str);
var_dump(strlen($str));

?>
```


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2016-06-16 04:49 UTC] stas@php.net

-Assigned To: +Assigned To: stas

 [2016-06-16 06:22 UTC] taoguangchen at icloud dot com

The patch looks OK.

 [2016-06-21 06:53 UTC] stas@php.net

-Status: Assigned +Status: Closed

 [2016-06-21 06:53 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-06-23 16:32 UTC] thomas at shadowweb dot org

I guess the fix in PHP_FUNCTION(nl2br) is incorrect:

int          new_length;
[...]
if (UNEXPECTED(new_length > INT_MAX)) {
[...]

This check will never trigger (since new_length is an int, obviously). You should also check str_len + 1 for an overflow against INT_MAX, since this variable may possibly also overflow when issuing the memory allocation:

int             str_len;
[...]
tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1);
[...]

 [2016-06-27 12:35 UTC] lampa at fit dot vutbr dot cz

The same applies to a "fix" in url.c, as y is also int.

 [2016-06-27 19:17 UTC] stas@php.net

Thanks, looks like I didn't notice those are int and not size_t :( I'll fix this.

However, str_len + 1 can't really overflow since str_len is int, but safe_emalloc accepts size_t, so worst that can happen seems to be str_len + 1 becomes big number and safe_emalloc fails with overflow.

 [2016-06-27 19:23 UTC] stas@php.net

I'm not sure which part of url.c you are referring to, as in my code I see:

	register size_t x, y;