Skip to content

Commit 3dc50aa

Browse files
committed
Fix GH-22046: The unserialize function with Uri\WhatWg\Url leads to NULL pointer dereference when object serialized back
The "C" serialization format is explicitly disabled.
1 parent 8680c3d commit 3dc50aa

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

ext/uri/php_uri.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,13 @@ PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object)
10571057
return &new_uri_object->std;
10581058
}
10591059

1060+
PHPAPI int php_uri_object_handler_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data)
1061+
{
1062+
zend_throw_exception_ex(NULL, 0, "Unserialization of %s using the \"C\" format is unsupported", ZSTR_VAL(ce->name));
1063+
1064+
return FAILURE;
1065+
}
1066+
10601067
PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser)
10611068
{
10621069
zend_string *key = zend_string_init_interned(uri_parser->name, strlen(uri_parser->name), true);
@@ -1079,6 +1086,7 @@ static PHP_MINIT_FUNCTION(uri)
10791086
php_uri_ce_rfc3986_uri = register_class_Uri_Rfc3986_Uri();
10801087
php_uri_ce_rfc3986_uri->create_object = php_uri_object_create_rfc3986;
10811088
php_uri_ce_rfc3986_uri->default_object_handlers = &object_handlers_rfc3986_uri;
1089+
php_uri_ce_rfc3986_uri->unserialize = &php_uri_object_handler_unserialize;
10821090
memcpy(&object_handlers_rfc3986_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
10831091
object_handlers_rfc3986_uri.offset = XtOffsetOf(php_uri_object, std);
10841092
object_handlers_rfc3986_uri.free_obj = php_uri_object_handler_free;
@@ -1087,6 +1095,7 @@ static PHP_MINIT_FUNCTION(uri)
10871095
php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url();
10881096
php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg;
10891097
php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri;
1098+
php_uri_ce_whatwg_url->unserialize = &php_uri_object_handler_unserialize;
10901099
memcpy(&object_handlers_whatwg_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
10911100
object_handlers_whatwg_uri.offset = XtOffsetOf(php_uri_object, std);
10921101
object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free;
@@ -1096,6 +1105,7 @@ static PHP_MINIT_FUNCTION(uri)
10961105
php_uri_ce_exception = register_class_Uri_UriException(zend_ce_exception);
10971106
php_uri_ce_error = register_class_Uri_UriError(zend_ce_error);
10981107
php_uri_ce_invalid_uri_exception = register_class_Uri_InvalidUriException(php_uri_ce_exception);
1108+
php_uri_ce_invalid_uri_exception->unserialize = &php_uri_object_handler_unserialize;
10991109
php_uri_ce_whatwg_invalid_url_exception = register_class_Uri_WhatWg_InvalidUrlException(php_uri_ce_invalid_uri_exception);
11001110
php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError();
11011111
php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType();

ext/uri/tests/gh22046.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
GH-22046: The unserialize function with Uri\WhatWg\Url leads to NULL pointer dereference when object serialized back
3+
--FILE--
4+
<?php
5+
6+
$payload = 'C:14:"Uri\WhatWg\Url":0:{}';
7+
try {
8+
unserialize($payload);
9+
} catch (Throwable $e) {
10+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
11+
}
12+
13+
$payload = 'C:15:"Uri\Rfc3986\Uri":0:{}';
14+
try {
15+
unserialize($payload);
16+
} catch (Throwable $e) {
17+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
18+
}
19+
?>
20+
--EXPECT--
21+
Exception: Unserialization of Uri\WhatWg\Url using the "C" format is unsupported
22+
Exception: Unserialization of Uri\Rfc3986\Uri using the "C" format is unsupported

0 commit comments

Comments
 (0)