From 97a90f43617badc7b917d51f6138a7387ab03a46 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 13 Dec 2025 10:20:58 +0000 Subject: [PATCH 1/2] Fix GH-20678: resource created by GlobIterator crashes with fclose(). close GH-20697 --- NEWS | 4 ++++ ext/spl/spl_directory.c | 5 +++++ ext/spl/tests/gh20678.phpt | 14 ++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 ext/spl/tests/gh20678.phpt diff --git a/NEWS b/NEWS index 007faa024956..ed2c4149a03f 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ PHP NEWS - LDAP: . Fix memory leak in ldap_set_options(). (ndossche) +- SPL: + . Fixed bug GH-20678 (resource created by GlobIterator crashes with fclose()). + (David Carlier) + - Standard: . Fix error check for proc_open() command. (ndossche) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 0a4d1456d65e..16bb6a11e521 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -306,6 +306,11 @@ static void spl_filesystem_dir_open(spl_filesystem_object* intern, zend_string * intern->type = SPL_FS_DIR; intern->u.dir.dirp = php_stream_opendir(ZSTR_VAL(path), REPORT_ERRORS, FG(default_context)); + if (intern->u.dir.dirp) { + /* we prevent potential UAF with conflicting explicit fclose(), relying on the object destructor for this */ + intern->u.dir.dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE; + } + if (ZSTR_LEN(path) > 1 && IS_SLASH_AT(ZSTR_VAL(path), ZSTR_LEN(path)-1)) { intern->path = zend_string_init(ZSTR_VAL(path), ZSTR_LEN(path)-1, 0); } else { diff --git a/ext/spl/tests/gh20678.phpt b/ext/spl/tests/gh20678.phpt new file mode 100644 index 000000000000..243f8cef06d1 --- /dev/null +++ b/ext/spl/tests/gh20678.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20678 (resource created by GlobalIterator crashes when it is called with fclose()) +--CREDITS-- +chongwick +--FILE-- + +--EXPECTF-- + +Warning: fclose(): %d is not a valid stream resource in %s on line %d From 526938648efe12f96f29fef3e346e215810105af Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:35:03 +0100 Subject: [PATCH 2/2] Fix test for 8.5+ --- ext/spl/tests/gh20678.phpt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/spl/tests/gh20678.phpt b/ext/spl/tests/gh20678.phpt index 243f8cef06d1..00364db7f804 100644 --- a/ext/spl/tests/gh20678.phpt +++ b/ext/spl/tests/gh20678.phpt @@ -10,5 +10,4 @@ $resource = end($resources); fclose($resource); ?> --EXPECTF-- - -Warning: fclose(): %d is not a valid stream resource in %s on line %d +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d