Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<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

Your e-mail address:

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

Powered by Openwall GNU/*/Linux - Powered by OpenVZ