Skip to content

Fix unregistering ini entries of dynamically loaded extension - #8435

Merged
arnaud-lb merged 1 commit into
php:PHP-8.1from
arnaud-lb:issue-8185
May 6, 2022
Merged

arnaud-lb merged 1 commit into
php:PHP-8.1from
arnaud-lb:issue-8185

Conversation

@arnaud-lb

@arnaud-lb arnaud-lb commented Apr 24, 2022 •

Copy link
Copy Markdown
Member

This fixes a crash involving ZTS and dl().

In ZTS, the global registered_zend_ini_directives is copied to a thread-specific EG(ini_entries). Extensions loaded with dl() register their ini entries in EG(ini_entries), however they unregister them from registered_zend_ini_directives, which has no effect and leaves the entries in EG(ini_entries). This leads to problems when destroying EG(ini_entries) later, because it references resources that are already freed.

This change ensures that MODULE_TEMPORARY modules will unregister their entries from EG(ini_entries).

I added a test extension specifically for the purpose of testing dl(). I could have used the zend_test for that, but I felt that with a dedicated extension it would be harder to accidentally nerf/no-op the tests.

@arnaud-lb
arnaud-lb force-pushed the issue-8185 branch 2 times, most recently from 4e62576 to 31c303f Compare April 24, 2022 12:06
@arnaud-lb
arnaud-lb changed the base branch from master to PHP-8.1 April 24, 2022 12:06
@cmb69

cmb69 commented Apr 27, 2022

Copy link
Copy Markdown
Member

This is supposed to fix #8185, I think.

Comment thread ext/standard/tests/general_functions/dl-001.phpt Outdated
@arnaud-lb
arnaud-lb force-pushed the issue-8185 branch 4 times, most recently from e9c08ee to 45c10f5 Compare April 29, 2022 20:54
@arnaud-lb
arnaud-lb marked this pull request as ready for review April 29, 2022 21:54
@arnaud-lb
arnaud-lb requested review from Girgias and cmb69 April 29, 2022 21:54

@cmb69 cmb69 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.

Thank you for the PR! Before more detailed review, we need to clarify whether this constitutes an ABI break (if so, we cannot target any of the stable PHP versions).

Comment thread Zend/zend_ini.h Outdated

@cmb69 cmb69 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.

Overall, this looks good to me, but I left some style nits.

Comment thread ext/dl_test/.gitignore Outdated

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.

Do we really need this file? Isn't that already handled by .gitignore in the root?

Comment thread ext/dl_test/dl_test.c Outdated

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.

I think you should add yourself as author.

Comment thread ext/dl_test/php_dl_test.h Outdated

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.

I don't see the point in having an own version for a bundled extension; consider to use PHP_VERSION instead of some hard-coded value.

Comment thread ext/dl_test/tests/skip.inc Outdated

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.

I prefer

Suggested change
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
if (PHP_OS_FAMILY === 'Windows') {

Comment thread ext/dl_test/tests/skip.inc Outdated

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.

Do we have to cater to macOS which uses .dylib as far as I know?

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.

I checked because I was not sure. The PHP build appears to generate .so files. The CI looks ok too (no mention of skipping or failing these tests).

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.

I very much prefer to explicitly have the closing PHP tags in .phpt files, so that syntax highlighting works.

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.

Aren't they also required for another reason? But yes I agree adding the closing tags is better

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.

No. The sections containing PHP code are extracted to temporary files, so closing tags are not strictly needed.

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.

For me personally it's because I like to be able to run tests quickly without invoking run-tests, by just doing php thetest.phpt

@Girgias Girgias 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.

Other than the PHPT test changes LGTM

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.

Suggested change
<?php include __DIR__ . "/../../../dl_test/tests/skip.inc";
<?php include dirname(__DIR__, 3) . "/dl_test/tests/skip.inc";

Might be 2, not sure of the top of my head.

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.

Aren't they also required for another reason? But yes I agree adding the closing tags is better

Comment thread Zend/zend_ini.c
* lead to death.
*/
if (directives != EG(ini_directives)) {
ZEND_ASSERT(module_type == MODULE_TEMPORARY);

@bukka bukka Oct 6, 2023 •

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.

@arnaud-lb just stumbled on this when fixing FPM extension loading using php_admin_value[extension] . It actaully uses php_dl and initializes permanent module so this is actually not going to work so I had to remove this assertion in #12277 . FPM is single threaded so it should not impact this issue - it just really needs to remove the assertion.

There might be potentially other issues with using dl for permanent modules and it has got some limitation but think the whole concept of using php_dl in FPM is really problematic which will require some bigger changes in FPM to get it rif of it (introduction of pool manager).

Anyway if you see some bigger problem with my change, please comment on that PR.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants