Bug 1297730

Summary: php: Type Confusion Vulnerability in PHP_to_XMLRPC_worker()
Product: [Other] Security Response Reporter: Adam Mariš <amaris>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED WONTFIX QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: abhgupta, carnil, cbuissar, dmcphers, fedora, jialiu, jokerman, jorton, kseifried, lmeyer, mmaslano, mmccomas, rcollet, tiwillia, webstack-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: php 5.5.31, php 5.6.17 Doc Type: Bug Fix
Doc Text:
A type confusion vulnerability was found in the PHP_to_XMLRPC_worker() function of PHP's XMLRPC extension. A remote attacker could exploit this flaw to disclose server memory or crash a PHP application.
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-02-03 12:36:21 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1297731    
Bug Blocks: 1297732    

Description Adam Mariš 2016-01-12 10:33:12 UTC
It was found that an attacker can control type and val via get_zval_xmlrpc_type() with a crafted object-type ZVAL. Z_STRVAL_P macro and the Z_STRLEN_P macro handles a non-string-type val, which is able to look up an arbitrary memory address. This results in leaking arbitrary memory blocks, crash application or other issues.

Vulnerable code:

static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int depth TSRMLS_DC)
{
	XMLRPC_VALUE xReturn = NULL;

	if (in_val) {
		zval* val = NULL;
		XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val);
	
		if (val) {
			switch (type) {
				case xmlrpc_base64:
					if (Z_TYPE_P(val) == IS_NULL) {
						xReturn = XMLRPC_CreateValueEmpty();
						XMLRPC_SetValueID(xReturn, key, 0);
					} else {
						xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
					}
					break;
				case xmlrpc_datetime:
					convert_to_string(val);
					xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val));
					break;
...
XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue) /* {{{ */
{
	XMLRPC_VALUE_TYPE type = xmlrpc_none;
	TSRMLS_FETCH();

	if (value) {
		switch (Z_TYPE_P(value)) {
			...
			case IS_OBJECT:
				{
					zval** attr;
					type = xmlrpc_vector;

					if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) {
						if (Z_TYPE_PP(attr) == IS_STRING) {
							type = xmlrpc_str_as_type(Z_STRVAL_PP(attr));
						}
					}
					break;
				}
		}

		/* if requested, return an unmolested (magic removed) copy of the value */
		if (newvalue) {
			zval** val;

			if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) {
				if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR), (void**) &val) == SUCCESS) {
					*newvalue = *val;
				}
			} else {
				*newvalue = value;
			}
		}

Upstream patch:

http://git.php.net/?p=php-src.git;a=commit;h=f3c1863aa2721343245b63ac7bd68cfdc3dd41f3

Upstream bug (contains reproducer):

https://bugs.php.net/bug.php?id=70728

Comment 1 Adam Mariš 2016-01-12 10:35:14 UTC
Created php tracking bugs for this issue:

Affects: fedora-all [bug 1297731]

Comment 2 Fedora Update System 2016-01-16 13:22:01 UTC
php-5.6.17-1.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.

Comment 3 Fedora Update System 2016-01-16 14:20:41 UTC
php-5.6.17-1.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.