Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Mon, 18 May 2015 10:18:27 +0200
From: Andrea Palazzo <andrea.palazzo@...el.it>
To: cve-assign@...re.org
CC: oss-security@...ts.openwall.com, security@....net
Subject: CVE Request + Advisory: PHP str_repeat() sign mismatch based memory
 corruption

Hi everyone,
this is intended as CVE Request and advisory for 
https://bugs.php.net/bug.php?id=69403.

## Info
#
#  Title: PHP str_repeat() sign mismatch based memory corruption
#  Author: Andrea Palazzo
#                  <andrea [dot] palazzo [at] truel [dot] it>
#                    http://www.truel.it
#  Product: PHP
#                     <= 5.4.40 / 5.5.24 / 5.6.8
#                     http://www.php.net
#     Patch: 
http://git.php.net/?p=php-src.git;a=commit;h=c591f022f8abb4c0c2e60a037a0c0c5c5a125957
# 
http://git.php.net/?p=php-src.git;a=commit;h=0a96aa600d1028eda505270366df28e4085a1941
#  CVE:     Not assigned yet
#
## Summary

str_repeat() suffers from a sign mismatch based integer overflow that 
results in creation of corrupted ZVALs; this condition, depending on the 
context, can be abused to bypass PHP-level checks or trigger any kind of 
memory error: a successful exploitation of this issue is likely to 
produce both local and remote code execution vectors.

## Details

str_repeat() takes mult as second argument, which represents the number 
of desired repetitions for the string passed as first argument. Once 
retrieved, this value is multiplied by input_len and stored into result_len

     /* Initialize the result string */
4907    result_len = input_len * mult;

which then, on line 4930 is passed as argument for RETURN_STRINGL() macro.
It should be noticed that while RETURN_STRINGL() ends up calling 
ZVAL_STRINGL(), which expects the length argument to be a signed int, 
result_len is defined as size_t, producing an implicit cast of the 
actual value.
In situations in which huge memory allocations are possible (most likely 
64-bit systems), it is possible to take advantage of this situation 
overflowing ZVAL_STRINGL's length into a negative value, in order to get 
a corrupted string-typed ZVAL.

(gdb) r -r 'var_dump(str_repeat("a", 4294967294+1));'

Breakpoint 1, php_var_dump (struc=0x7ffff7f8a188, level=level@...ry=1)
     at /build/buildd/php5-5.6.7+dfsg/ext/standard/var.c:88
88    /build/buildd/php5-5.6.7+dfsg/ext/standard/var.c: No such file or 
directory.
(gdb) p **struc
$7 = {value = {lval = 140732723359792, dval = 6,9531203857753119e-310, 
str = {
       val = 0x7ffee3fbf030 'a' <repeats 200 times>..., len = -1},
     ht = 0x7ffee3fbf030, obj = {handle = 3824939056,
       handlers = 0x7fffffffffff}, ast = 0x7ffee3fbf030}, refcount__gc = 1,
   type = 6 '\006', is_ref__gc = 0 '\000'}

## Solution

Update to PHP 5.4.41 / 5.5.25 / 5.6.9
http://php.net/downloads.php

## Timeline

2015-04-09 - Privately submitted through PHP Bug tracking system
2015-05-10 - Assigned
2015-05-12 - Patch issued

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.