Fix GH-17037: UAF in user filter when adding existing filter name due to incorrect error handling

There are two functions that can each fail in their own way. If the last
function fails we have to remove the filter entry from the hash table,
otherwise we risk a UAF. Note also that removing the entry from the
table on failure will also free its memory.

Closes GH-17038.
This commit is contained in:
Niels Dossche
2024-12-03 22:47:53 +01:00
parent 9c40bdaaf5
commit 00f4881e90
3 changed files with 19 additions and 4 deletions

3
NEWS
View File

@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.3.16
- Streams:
. Fixed bug GH-17037 (UAF in user filter when adding existing filter name due
to incorrect error handling). (nielsdos)
19 Dec 2024, PHP 8.3.15

View File

@ -0,0 +1,8 @@
--TEST--
GH-17037 (UAF in user filter when adding existing filter name due to incorrect error handling)
--FILE--
<?php
var_dump(stream_filter_register('string.toupper', 'filter_string_toupper'));
?>
--EXPECT--
bool(false)

View File

@ -516,13 +516,17 @@ PHP_FUNCTION(stream_filter_register)
fdat = ecalloc(1, sizeof(struct php_user_filter_data));
fdat->classname = zend_string_copy(classname);
if (zend_hash_add_ptr(BG(user_filter_map), filtername, fdat) != NULL &&
php_stream_filter_register_factory_volatile(filtername, &user_filter_factory) == SUCCESS) {
RETVAL_TRUE;
if (zend_hash_add_ptr(BG(user_filter_map), filtername, fdat) != NULL) {
if (php_stream_filter_register_factory_volatile(filtername, &user_filter_factory) == SUCCESS) {
RETURN_TRUE;
}
zend_hash_del(BG(user_filter_map), filtername);
} else {
zend_string_release_ex(classname, 0);
efree(fdat);
RETVAL_FALSE;
}
RETURN_FALSE;
}
/* }}} */