Skip to content

Conversation

@ndossche
Copy link
Member

@ndossche ndossche commented Jan 3, 2026

If user code runs after modules executed RSHUTDOWN, it can be dangerous because user code can rely on module globals that have already been invalidated.
We should not run user code after RSHUTDOWN.

This is shown by the test by using putenv(). The original report demonstrated a silent failure via mbstring. There are more test cases possible but this is by far the simplest.

An alternative solution would be to try to separate the user code running via php_header() from the output layer shutdown, to make sure user code runs earlier. However, that becomes an ugly complex solution. This PR's solution keeps things simple but this can be a BC break if extensions produce output in their RSHUTDOWN handler (However, that may have been unsafe in the first place).

…the output layer

If user code runs after modules executed RSHUTDOWN, it can be dangerous
because user code can rely on module globals that have already been
invalidated.
We should not run user code after RSHUTDOWN.

This is shown by the test by using putenv(). The original report
demonstrated a silent failure via mbstring. There are more test cases
possible but this is by far the simplest.

An alternative solution would be to try to separate the user code
running via php_header() from the output layer shutdown, to make sure
user code runs earlier. However, that becomes an ugly complex solution.
This PR's solution keeps things simple but this can be a BC break if
extensions produce output in their RSHUTDOWN handler (However, that may
have been unsafe in the first place).
@bukka
Copy link
Member

bukka commented Jan 3, 2026

@ndossche This is just a test.. Did you forget to push something else?

@ndossche
Copy link
Member Author

ndossche commented Jan 3, 2026

@ndossche This is just a test.. Did you forget to push something else?

Woops! Indeed, now pushed.

Copy link
Member

@bukka bukka left a comment

Choose a reason for hiding this comment

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

I have been just thinking about it and can't think about use case with outupt in request shutdown. I think it should be fine for master. Please update UPGRADING.INTERNALS

@iluuu1994
Copy link
Member

iluuu1994 commented Jan 3, 2026

I don't mind the BC break for master if it's documented and attempting to produce output in RSHUTDOWN triggers an error/assertion.

@ndossche
Copy link
Member Author

ndossche commented Jan 3, 2026

I'm discovering some more things now:

  1. Producing output after this patch still works, just won't go through the output handlers set by the user.
  2. The session module can output warnings on RSHUTDOWN.
  3. The session module has the same bug as this patch tries to solve. This is because on RSHUTDOWN of ext/session, it can flush the session, which can in turn trigger running user code. If that user code relies on extensions that already had their RSHUTDOWN called we can run into the same issues demonstrated by the phpt test in this PR (e.g. UAF, assertion failures, ...)

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.

User code can run after module request shutdown via the output layer

3 participants