Skip to content

Commit 00f4881

Browse files
committed
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.
1 parent 9c40bda commit 00f4881

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.16
44

5+
- Streams:
6+
. Fixed bug GH-17037 (UAF in user filter when adding existing filter name due
7+
to incorrect error handling). (nielsdos)
58

69
19 Dec 2024, PHP 8.3.15
710

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
GH-17037 (UAF in user filter when adding existing filter name due to incorrect error handling)
3+
--FILE--
4+
<?php
5+
var_dump(stream_filter_register('string.toupper', 'filter_string_toupper'));
6+
?>
7+
--EXPECT--
8+
bool(false)

ext/standard/user_filters.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,13 +516,17 @@ PHP_FUNCTION(stream_filter_register)
516516
fdat = ecalloc(1, sizeof(struct php_user_filter_data));
517517
fdat->classname = zend_string_copy(classname);
518518

519-
if (zend_hash_add_ptr(BG(user_filter_map), filtername, fdat) != NULL &&
520-
php_stream_filter_register_factory_volatile(filtername, &user_filter_factory) == SUCCESS) {
521-
RETVAL_TRUE;
519+
if (zend_hash_add_ptr(BG(user_filter_map), filtername, fdat) != NULL) {
520+
if (php_stream_filter_register_factory_volatile(filtername, &user_filter_factory) == SUCCESS) {
521+
RETURN_TRUE;
522+
}
523+
524+
zend_hash_del(BG(user_filter_map), filtername);
522525
} else {
523526
zend_string_release_ex(classname, 0);
524527
efree(fdat);
525-
RETVAL_FALSE;
526528
}
529+
530+
RETURN_FALSE;
527531
}
528532
/* }}} */

0 commit comments

Comments
 (0)