Skip to content

ext/session: fix missing zval_ptr_dtor for retval in PS_GC_FUNC(user)#21747

Closed
jorgsowa wants to merge 2 commits intophp:PHP-8.4from
jorgsowa:fix/session-gc-retval-leak
Closed

ext/session: fix missing zval_ptr_dtor for retval in PS_GC_FUNC(user)#21747
jorgsowa wants to merge 2 commits intophp:PHP-8.4from
jorgsowa:fix/session-gc-retval-leak

Conversation

@jorgsowa
Copy link
Copy Markdown
Contributor

PS_GC_FUNC(user) did not call zval_ptr_dtor() on the return value of the user GC callback, leaking memory when the callback returned a reference-counted value. All other user handlers (write, destroy, validate_sid, update_timestamp) already free retval correctly.

Copy link
Copy Markdown
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

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

Needs to be backported to 8.4.

PS_GC_FUNC(user) did not call zval_ptr_dtor() on the return value of
the user GC callback, leaking memory when the callback returned a
reference-counted value. All other user handlers (write, destroy,
validate_sid, update_timestamp) already free retval correctly.
@jorgsowa jorgsowa force-pushed the fix/session-gc-retval-leak branch from 1c709a2 to 2330863 Compare April 15, 2026 08:39
@jorgsowa jorgsowa changed the base branch from master to PHP-8.4 April 15, 2026 08:40
function(string $id): string|false { return ""; },
function(string $id, string $data) { return true; },
function(string $id) { return true; },
function(int $max) { return str_repeat("x", 100); }
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.

Just FYI: this won't leak when the test runs with opcache, which nowadays is almost always. This is because of SCCP computing the string at compile time which causes the string to get interned.
To solve this, replace 100 by random_int(100, 100)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you

Comment thread ext/session/mod_user.c
/* Anything else is some kind of error */
*nrdels = -1; // Error
}
zval_ptr_dtor(&retval);
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.

Why not only do this in the error case?
Besides there's a subtle additional problem in the callback code: it doesn't handle reference returns (this may be solved in ps_call_handler).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for this comment. I need to still apply it, but in different PR. CC: @Girgias this hasn't been addressed yet, but I think it may be addressed in differnt PR

@Girgias
Copy link
Copy Markdown
Member

Girgias commented Apr 20, 2026

@jorgsowa can you address Nora's remarks?

Use random_int(100, 100) to defeat SCCP constant folding, which would
otherwise intern the str_repeat result at compile time under opcache
and make the leak unobservable.
Copy link
Copy Markdown
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

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

Thank you :)

@Girgias Girgias closed this in d965793 Apr 21, 2026
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.

3 participants