Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1c18267

Browse files
Destroy temporary module classes in reverse order
We destroy classes of dl()'ed modules in clean_module_classes(), during shutdown. Child classes of a module use structures of the parent class (such as inherited properties), which are destroyed earlier, so we have a use-after-free when destroying a child class. Here I destroy classes in reverse order, as it is done in zend_shutdown() for persistent classes. Fixes GH-17961 Fixes GH-15367
1 parent a7d2703 commit 1c18267

File tree

5 files changed

+97
-14
lines changed

5 files changed

+97
-14
lines changed

‎NEWS‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.20
44

5+
- Core:
6+
. Fixed bug GH-17961 (use-after-free during dl()'ed module class destruction).
7+
(Arnaud)
8+
. Fixed bug GH-15367 (dl() of module with aliased class crashes in shutdown).
9+
(Arnaud)
10+
511
- DOM:
612
. Fix weird unpack behaviour in DOM. (nielsdos)
713

‎Zend/zend_API.c‎

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "zend.h"
2323
#include "zend_execute.h"
2424
#include "zend_API.h"
25+
#include "zend_hash.h"
2526
#include "zend_modules.h"
2627
#include "zend_extensions.h"
2728
#include "zend_constants.h"
@@ -3111,21 +3112,17 @@ ZEND_API zend_result zend_get_module_started(const char *module_name) /* {{{ */
31113112
}
31123113
/* }}} */
31133114

3114-
static int clean_module_class(zval *el, void *arg) /* {{{ */
3115-
{
3116-
zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
3117-
int module_number = *(int *)arg;
3118-
if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
3119-
return ZEND_HASH_APPLY_REMOVE;
3120-
} else {
3121-
return ZEND_HASH_APPLY_KEEP;
3122-
}
3123-
}
3124-
/* }}} */
3125-
31263115
static void clean_module_classes(int module_number) /* {{{ */
31273116
{
3128-
zend_hash_apply_with_argument(EG(class_table), clean_module_class, (void *) &module_number);
3117+
/* Child classes may reuse structures from parent classes, so destroy in reverse order. */
3118+
Bucket *bucket;
3119+
ZEND_HASH_REVERSE_FOREACH_BUCKET(EG(class_table), bucket) {
3120+
zend_class_entry *ce = Z_CE(bucket->val);
3121+
if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
3122+
zend_hash_del_bucket(EG(class_table), bucket);
3123+
}
3124+
} ZEND_HASH_FOREACH_END();
3125+
31293126
}
31303127
/* }}} */
31313128

‎ext/dl_test/dl_test.c‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,22 @@ PHP_METHOD(DlTest, test)
9292
RETURN_STR(retval);
9393
}
9494

95+
PHP_METHOD(DlTestSuperClass, test)
96+
{
97+
ZEND_PARSE_PARAMETERS_NONE();
98+
99+
RETURN_NULL();
100+
}
101+
95102
/* {{{ PHP_MINIT_FUNCTION */
96103
PHP_MINIT_FUNCTION(dl_test)
97104
{
105+
zend_class_entry *ce;
106+
98107
register_class_DlTest();
108+
ce = register_class_DlTestSuperClass();
109+
register_class_DlTestSubClass(ce);
110+
register_class_DlTestAliasedClass();
99111

100112
/* Test backwards compatibility */
101113
if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) {

‎ext/dl_test/dl_test.stub.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ function dl_test_test2(string $str = ""): string {}
1212
class DlTest {
1313
public function test(string $str = ""): string {}
1414
}
15+
16+
class DlTestSuperClass {
17+
public int $a;
18+
public function test(string $str = ""): string {}
19+
}
20+
21+
class DlTestSubClass extends DlTestSuperClass {
22+
}
23+
24+
/** @alias DlTestClassAlias */
25+
class DlTestAliasedClass {
26+
}

‎ext/dl_test/dl_test_arginfo.h‎

Lines changed: 57 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /