Skip to content

Commit dd9c57c

Browse files
support neighbouring extension in the ZendMM custom handlers hook
1 parent ebb4488 commit dd9c57c

File tree

4 files changed

+55
-22
lines changed

4 files changed

+55
-22
lines changed

ext/zend_test/php_test.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,15 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
5656
bool print_stderr_mshutdown;
5757
zend_long limit_copy_file_range;
5858
int observe_opline_in_zendmm;
59+
// previous heap from ZendMM
5960
zend_mm_heap* zend_orig_heap;
61+
// custom heap with custom handlers
6062
zend_mm_heap* zend_test_heap;
63+
// previous handlers that might have been installed
64+
// `USE_ZEND_ALLOC=0` installs custom handlers
65+
void* (*zendmm_orig_malloc)(size_t);
66+
void (*zendmm_orig_free)(void*);
67+
void* (*zendmm_orig_realloc)(void *, size_t);
6168
zend_test_fiber *active_fiber;
6269
zend_long quantity_value;
6370
zend_string *str_test;

ext/zend_test/test.c

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ void * zend_test_custom_malloc(size_t len)
522522
if (has_opline(EG(current_execute_data))) {
523523
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
524524
}
525+
if (ZT_G(zendmm_orig_malloc)) {
526+
return ZT_G(zendmm_orig_malloc)(len);
527+
}
525528
return _zend_mm_alloc(ZT_G(zend_orig_heap), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
526529
}
527530

@@ -530,6 +533,10 @@ void zend_test_custom_free(void *ptr)
530533
if (has_opline(EG(current_execute_data))) {
531534
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
532535
}
536+
if (ZT_G(zendmm_orig_free)) {
537+
ZT_G(zendmm_orig_free)(ptr);
538+
return;
539+
}
533540
_zend_mm_free(ZT_G(zend_orig_heap), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
534541
}
535542

@@ -538,9 +545,47 @@ void * zend_test_custom_realloc(void * ptr, size_t len)
538545
if (has_opline(EG(current_execute_data))) {
539546
assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
540547
}
548+
if (ZT_G(zendmm_orig_realloc)) {
549+
return ZT_G(zendmm_orig_realloc)(ptr, len);
550+
}
541551
return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
542552
}
543553

554+
void zend_test_install_custom_mm_handler(void)
555+
{
556+
// fetch maybe installed previous handlers
557+
if (!is_zend_mm()) {
558+
zend_mm_get_custom_handlers(
559+
zend_mm_get_heap(),
560+
&ZT_G(zendmm_orig_malloc),
561+
&ZT_G(zendmm_orig_free),
562+
&ZT_G(zendmm_orig_realloc)
563+
);
564+
}
565+
// `zend_mm_heap` is a private struct, so we have not way to find the
566+
// actual size, but 4096 bytes should be enough
567+
ZT_G(zend_test_heap) = malloc(4096);
568+
memset(ZT_G(zend_test_heap), 0, 4096);
569+
zend_mm_set_custom_handlers(
570+
ZT_G(zend_test_heap),
571+
zend_test_custom_malloc,
572+
zend_test_custom_free,
573+
zend_test_custom_realloc
574+
);
575+
ZT_G(zend_orig_heap) = zend_mm_get_heap();
576+
zend_mm_set_heap(ZT_G(zend_test_heap));
577+
}
578+
579+
void zend_test_uninstall_custom_mm_handler(void)
580+
{
581+
free(ZT_G(zend_test_heap));
582+
ZT_G(zend_test_heap) = NULL;
583+
ZT_G(zendmm_orig_malloc) = NULL;
584+
ZT_G(zendmm_orig_free) = NULL;
585+
ZT_G(zendmm_orig_realloc) = NULL;
586+
zend_mm_set_heap(ZT_G(zend_orig_heap));
587+
}
588+
544589
static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
545590
{
546591
if (new_value == NULL) {
@@ -550,22 +595,9 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
550595
int int_value = zend_ini_parse_bool(new_value);
551596

552597
if (int_value == 1) {
553-
// `zend_mm_heap` is a private struct, so we have not way to find the
554-
// actual size, but 4096 bytes should be enough
555-
ZT_G(zend_test_heap) = malloc(4096);
556-
memset(ZT_G(zend_test_heap), 0, 4096);
557-
zend_mm_set_custom_handlers(
558-
ZT_G(zend_test_heap),
559-
zend_test_custom_malloc,
560-
zend_test_custom_free,
561-
zend_test_custom_realloc
562-
);
563-
ZT_G(zend_orig_heap) = zend_mm_get_heap();
564-
zend_mm_set_heap(ZT_G(zend_test_heap));
598+
zend_test_install_custom_mm_handler();
565599
} else if (ZT_G(zend_test_heap)) {
566-
free(ZT_G(zend_test_heap));
567-
ZT_G(zend_test_heap) = NULL;
568-
zend_mm_set_heap(ZT_G(zend_orig_heap));
600+
zend_test_uninstall_custom_mm_handler();
569601
}
570602
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
571603
}
@@ -971,9 +1003,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
9711003
zend_hash_destroy(&ZT_G(global_weakmap));
9721004

9731005
if (ZT_G(zend_test_heap)) {
974-
free(ZT_G(zend_test_heap));
975-
ZT_G(zend_test_heap) = NULL;
976-
zend_mm_set_heap(ZT_G(zend_orig_heap));
1006+
zend_test_uninstall_custom_mm_handler();
9771007
}
9781008

9791009
return SUCCESS;

ext/zend_test/tests/opline_dangling.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ possible segfault in `ZEND_BIND_STATIC`
44
https://github.com/php/php-src/pull/12758
55
--EXTENSIONS--
66
zend_test
7-
--ENV--
8-
USE_ZEND_ALLOC=1
97
--INI--
108
zend_test.observe_opline_in_zendmm=1
119
--FILE--

ext/zend_test/tests/opline_dangling_02.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
possible segfault in `ZEND_FUNC_GET_ARGS`
33
--EXTENSIONS--
44
zend_test
5-
--ENV--
6-
USE_ZEND_ALLOC=1
75
--INI--
86
zend_test.observe_opline_in_zendmm=1
97
--FILE--

0 commit comments

Comments
 (0)