-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apache crash on Windows when using a self-referencing anonymous function inside a class with an active mysqli connection #10599
Comments
@kamil-tekiela can you maybe have a look at this to see if you can reproduce it? Don't remember the sets to getting ext/mysqli test suit running locally |
I can reproduce it on Windows.
The MCVE is:
This begs the question: if it's so easily reproducible, does this mean nobody uses this feature? |
Because it only crashes on shutdown, so for most SAPIs that takes a while until it crashes; and the SAPI just start the process automatically on a crash. It's very visible on CGI and CLI though where it will crash after handling the request/file. What happens is that the persistent network stream resource gets freed, yet stays inside EG(persistent_list). This causes a crash on shutdown when the persistent list is getting cleared, as the engine will try to free the network stream again. php-src/ext/mysqlnd/mysqlnd_vio.c Lines 654 to 665 in bb1ef4f
Notice how it checks for So for master, the fix it simple: remove that On lower branches, it's trickier. Although on the surface level it seems that the same fix also works there (I tried this), it might still run into the issue that the persistent list is destroyed, although I'm not entirely certain how hard it is to trigger that. Then again, if we crash already with the existing code, we might as well change it anyway? In any case: on master it's a safe fix, on lower branches not necessarily. I could create a PR for master, and leave this as-is for lower branches; the only thing that remains then is how we're going to create a phpt file for this. This would need a named pipe (or are there other ways to reproduce this too?) and I'm not sure how to set that up into CI... @kamil-tekiela If you have any thoughts on this, I'd be happy to read them 🙂 |
@nielsdos If you can fix it on master and test locally that it resolves the problem then I think that would be sufficient for now. We can keep this issue open and think how to add a proper test and fix it on lower branches. |
What happens is that the persistent network stream resource gets freed, yet stays inside EG(persistent_list). This causes a crash on shutdown when the persistent list is getting cleared, as the engine will try to free the network stream again. The code in close_stream gets confused between persistent vs non-persistent allocations when EG(active) is false. This code was introduced in c3019a1 to fix crashes when the persistent list gets destroyed before module shutdown is called. This is indeed a potential problem that was fixed on the master branch in 5941cda. This fixes the crash reason of phpGH-10599.
This fixes the memory leak part of phpGH-10599.
This prevents the code from getting desynced again, which was the reason for the leak of phpGH-10599.
…i connection The code originally posted in phpGH-10599 triggers the bug for non-persistent connections, but changing the host to `p:.` reveals that there is also a crash bug for persistent connections.
What happens is that the persistent network stream resource gets freed, yet stays inside EG(persistent_list). This causes a crash on shutdown when the persistent list is getting cleared, as the engine will try to free the network stream again. The code in close_stream gets confused between persistent vs non-persistent allocations when EG(active) is false. This code was introduced in c3019a1 to fix crashes when the persistent list gets destroyed before module shutdown is called. This is indeed a potential problem that was fixed on the master branch in 5941cda. This fixes the crash reason of phpGH-10599.
This fixes the memory leak part of phpGH-10599.
This prevents the code from getting desynced again, which was the reason for the leak of phpGH-10599.
…i connection The code originally posted in phpGH-10599 triggers the bug for non-persistent connections, but changing the host to `p:.` reveals that there is also a crash bug for persistent connections.
…i connection The code originally posted in phpGH-10599 triggers the bug for non-persistent connections, but changing the host to `p:.` reveals that there is also a crash bug for persistent connections.
What happens is that the persistent network stream resource gets freed, yet stays inside EG(persistent_list). This causes a crash on shutdown when the persistent list is getting cleared, as the engine will try to free the network stream again. The code in close_stream gets confused between persistent vs non-persistent allocations when EG(active) is false. This code was introduced in c3019a1 to fix crashes when the persistent list gets destroyed before module shutdown is called. This is indeed a potential problem that was fixed on the master branch in 5941cda. This fixes the crash reason of GH-10599.
This fixes the memory leak part of GH-10599.
This prevents the code from getting desynced again, which was the reason for the leak of GH-10599.
…i connection The code originally posted in GH-10599 triggers the bug for non-persistent connections, but changing the host to `p:.` reveals that there is also a crash bug for persistent connections.
This partially backports that PR to stable branches as it has been in master without reported problems so far. It's only a partial backport because the stable branches don't have the ZTS persistent resource fix that would fix shutdown crashes, i.e. the code change in mysqlnd_vio's close_stream is not backported. Closes phpGH-10599.
Description
The following code:
Resulted in this output:
But I expected this output instead:
I've tested much to find this bug. It only appears if you have a mysqli connection inside of the class instance.
Also you need to use a anonymous function with a use of the variable by reference where you assign the anonymous function.
As a workaround for me I will get rid of this anonymous function now. But however it should not be possible to crash the executing process like this.
PHP Version
PHP 8.1.14 (the bug exists since 7.4, in 7.3 there is no crash)
Operating System
Windows
The text was updated successfully, but these errors were encountered: