Skip to content

ext/session: Clear in_save_handler recursion guard on bailout - #23846

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:promote/session-bailout-guard
Open

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:promote/session-bailout-guard

Conversation

@iliaal

@iliaal iliaal commented Sep 22, 2026

Copy link
Copy Markdown
Member

A zend_bailout() out of a userland save handler, a fatal error inside write() for instance, skipped the PS(in_save_handler) = 0 store in ps_call_handler(), so the flag stayed set for the rest of the request and the shutdown flush refused to call the handler, reporting "Cannot call session save handler in a recursive manner". The new test forces a real out-of-memory bailout inside write() and checks that the following write() and close() still run. bug60634_error_3.phpt and bug60634_error_4.phpt asserted the old warning and now assert the close handler running.

Fixes #15529

Comment thread ext/session/mod_user.c Outdated
bailout = true;
} zend_end_try();
if (!bailout) {
PS(in_save_handler) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the code, it seems you can just set PS(in_save_handler) unconditionally to 0. Removing the assignment in the zend_catch block and removing the !bailout if-check.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the reset out of the catch, it runs unconditionally now.

ps_call_handler() set PS(in_save_handler) around call_user_function() with
no protection against a zend_bailout() from inside a userland save handler,
so a fatal error in open/read/write/close left the flag sticky: the shutdown
flush then reported "Cannot call session save handler in a recursive manner"
and skipped the pending handler calls. Wrap the invocation in
zend_try/zend_catch, clear the flag unconditionally once the block has run,
and defer the re-bail until after the argument cleanup. bug60634_error_3.phpt
and bug60634_error_4.phpt expected the sticky-flag warning and now expect the
close handler to run.

Fixes phpGH-15529
@iliaal
iliaal force-pushed the promote/session-bailout-guard branch from c651024 to 2b96d11 Compare September 22, 2026 15:56

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay but this is a behaviour change though, so deferring the final approval to an ext/session codeowner

@iliaal

iliaal commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

Agreed, may even need to rebase to just 8.6+, but it is a bug so I'll let the code owner make the final call here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants