php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
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
Status: Closed Package: *General Issues
PHP Version: 5.5.36 OS:
Private report: No CVE-ID:
 [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

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-16 04:49 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-06-16 04:49 UTC] stas@php.net
Not sure all of these are security issues but since I'm lazy I'll fix all of these in 5.5. with one patch. See 8bb003da20ce4a6d14b37a6de9faa685925da182 in security of https://gist.github.com/b7d11aa951ce3eda74379abaad0db882

Please verify
 [2016-06-16 04:52 UTC] stas@php.net
oops, forgot nl2br. Now 88746d60ab3ad51797612ee62603bb3e08d4aac4 and https://gist.github.com/282fcf1d02dc9583e3633e9d867adcec
 [2016-06-16 06:22 UTC] taoguangchen at icloud dot com
The patch looks OK.
 [2016-06-21 06:49 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88746d60ab3ad51797612ee62603bb3e08d4aac4
Log: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths
 [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-21 07:03 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88746d60ab3ad51797612ee62603bb3e08d4aac4
Log: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths
 [2016-06-21 07:26 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88746d60ab3ad51797612ee62603bb3e08d4aac4
Log: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths
 [2016-06-21 07:27 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88746d60ab3ad51797612ee62603bb3e08d4aac4
Log: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths
 [2016-06-22 05:58 UTC] krakjoe@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88746d60ab3ad51797612ee62603bb3e08d4aac4
Log: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths
 [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;
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC