Bug 683183 (CVE-2011-1092) - CVE-2011-1092 php: integer overflow in shmop_read()
Summary: CVE-2011-1092 php: integer overflow in shmop_read()
Keywords:
Status: CLOSED DUPLICATE of bug 169857
Alias: CVE-2011-1092
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-03-08 19:05 UTC by Vincent Danen
Modified: 2021-02-24 16:20 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-03-16 21:53:01 UTC
Embargoed:


Attachments (Terms of Use)

Description Vincent Danen 2011-03-08 19:05:36 UTC
It was reported [1],[2] that there was an integer overflow in PHP's shmop_read() function.  This function reads a given number of bytes from memory, at a given offset starting from a shared memory area.  With a sufficiently large value, more memory is allocated than there is space for, which could result in a segfault because PHP is reading past its own memory.  If there is enough allocated memory available, however, PHP could leak up to 2GB of arbitrary memory.

To test:

<?php
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, "c", 0644, 100);
$shm_data = shmop_read($shm_id, 1, 2147483647);
//if there is no segmentation fault past this point, we have 2gb of memory!
echo $shm_data;
?>

This sets a start value of 1, and 2^31 (2147483647) as the count:

2147483647+1 = -2147483647

This was corrected upstream [3] for version 5.3.6.

References:

[1] http://openwall.com/lists/oss-security/2011/03/08/9
[2] http://bugs.php.net/54193
[3] http://svn.php.net/viewvc/?view=revision&revision=309018

Comment 1 Vincent Danen 2011-03-08 19:10:09 UTC
It looks as though you would need to allow very high amounts of memory to PHP in order to achieve a segfault here.  Using the above test script on Red Hat Enterprise Linux 6:


% php --version
PHP 5.3.2 (cli) (built: Jan 19 2011 08:09:24) 
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
% egrep '^memory_limit' /etc/php.ini
memory_limit = 1280M
% php CVE-2011-1092.php 
PHP Fatal error:  Allowed memory size of 1342177280 bytes exhausted (tried to allocate 2147483648 bytes) in /tmp/CVE-2011-1092.php on line 4

I've not yet had a chance to look at older versions.

Comment 2 Joe Orton 2011-03-09 14:13:28 UTC
Yes, memory_limit is 128M the RHEL 5/6 default configs (and lower in older versions).  You can set to -1 to disable a limit for testing the script.

It does not seem likely or reasonable that a script will pass untrusted and unvalidated script input data to the shmop_* functions, so I'd say there is no trust boundary being crossed here.

Comment 6 Vincent Danen 2011-03-16 21:53:01 UTC
This is a duplicate.

*** This bug has been marked as a duplicate of bug 169857 ***

Comment 7 Tomas Hoger 2011-04-27 08:24:51 UTC
Few additional notes:

- The test case mentioned in comment #0 would not work on 64bit system such as x86_64 without changes.  The shmop_read uses (signed) long type to store start and count parameter values.  Test case passes INT_MAX as a count argument, to make bytes (== count) + 1 to overflow.  This can only happen if start + count overflows in the following check:

  start + count > shmop->size

That does not happen in this specific case on 64bit, as long can store 1 + INT_MAX without overflowing (int is 32bit, long is 64bit).  However, it is possible to modify the test to trigger crash on 64 bit too, as count value is assigned to int bytes variable, where truncation to 32 bits can happen and can lead to a crash similar to the one seen on 32bit systems.

- Additionally, that test case does not work on 32bit php packages in RHEL-4 and RHEL-5 (php-5.1.6, but it does work in php53-5.3.3), where PHP rejects memory allocations with negative size or size greater than INT_MAX.  On 32bit only INT_MAX value incorrectly passes start and count checks, which leads to an attempt to allocate INT_MIN bytes, which is rejected.  On 64bit, only 64bit LONG_MAX value incorrectly passes checks and leads to an attempt to allocate 0-sized buffer, which triggers the crash on subsequent memcpy.

Comment 8 Vincent Danen 2011-04-27 14:13:01 UTC
Statement:

Red Hat does not consider this to be a security issue. Input passed to these functions should be under the full control of the script author, thus no trust boundary is crossed.  Additionally, an administrator would have to disable, or excessively increase the memory_limit settings in the PHP configuration file to trigger this bug.

Comment 9 admin.web 2011-10-20 17:53:02 UTC
This is marked as a duplicate of 169857 but that doesn't seem correct based on reading that bug.

Also, comment 8 said that Red Hat doesn't consider this to be a security issue, but I would propose that it is because doesn't it allow an attacker increase the severity of an attack by gaining access to more data than they otherwise would have been able to get.

For example, consider a Red Hat server that is being used for shared hosting and it has one client's site on it that gets compromised (such as because it's running out of date open source software like WordPress) such that the attacker can run arbitrary code on that site only.  Now wouldn't they just call ini_set('memory_limit', '3000M'); in PHP code and thus be able to do the exploit and read other clients' data?

An important point of note is that the memory_limit setting doesn't just get set by an administrator, it also can be set in PHP scripts as it's of type PHP_INI_ALL (see us2.php.net/manual/en/ini.core.php#ini.sect.resource-limits)


Note You need to log in before you can comment on or make changes to this bug.