From 4bfab315cb2e69e89e00ed415414a29b6bcdcbd9 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 24 Aug 2026 12:23:20 -0400 Subject: [PATCH] [Session] destroy session file without an open descriptor PS_DESTROY_FUNC(files) skipped the unlink when data->fd was -1, so a destroy of a never-opened or already-closed session file returned SUCCESS while the file stayed on disk. The unlink now always runs after the optional ps_files_close(), tolerating ENOENT via the existing access() check. Sibling audit: PS_DESTROY_FUNC(mm) and mod_user have no descriptor gate, and the files close/read/write paths keep their existing descriptor handling. --- NEWS | 5 ++ ext/session/mod_files.c | 12 +--- .../tests/session_destroy_no_open_fd.phpt | 55 +++++++++++++++++++ 3 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 ext/session/tests/session_destroy_no_open_fd.phpt diff --git a/NEWS b/NEWS index 3346d38ea898..157e5ac148cb 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,11 @@ PHP NEWS registrations are freed while still reachable from the cycle collector. (Ilia Alshanetsky) +- Session: + . Fixed session_destroy() not removing the session file when the files + save handler holds no open descriptor for it. (Ilia Alshanetsky) + + 24 Sep 2026, PHP 8.4.26 diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 74e77973405b..36fd28f35e17 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -599,16 +599,10 @@ PS_DESTROY_FUNC(files) return FAILURE; } - if (data->fd != -1) { - ps_files_close(data); + ps_files_close(data); - if (VCWD_UNLINK(buf) == -1) { - /* This is a little safety check for instances when we are dealing with a regenerated session - * that was not yet written to disk. */ - if (!VCWD_ACCESS(buf, F_OK)) { - return FAILURE; - } - } + if (VCWD_UNLINK(buf) == -1 && !VCWD_ACCESS(buf, F_OK)) { + return FAILURE; } return SUCCESS; diff --git a/ext/session/tests/session_destroy_no_open_fd.phpt b/ext/session/tests/session_destroy_no_open_fd.phpt new file mode 100644 index 000000000000..4dd684f44a5d --- /dev/null +++ b/ext/session/tests/session_destroy_no_open_fd.phpt @@ -0,0 +1,55 @@ +--TEST-- +Session files: destroy removes session file even without an open descriptor +--INI-- +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(false) +end