Skip to content

Commit dc9808b

Browse files
committed
Refresh zend_mm shadow key on fork
1 parent 382be92 commit dc9808b

File tree

9 files changed

+53
-15
lines changed

9 files changed

+53
-15
lines changed

Zend/zend_alloc.c

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@
7070
# include <wincrypt.h>
7171
# include <process.h>
7272
# include "win32/winutil.h"
73-
# define getpid _getpid
74-
typedef int pid_t;
7573
#endif
7674

7775
#include <stdio.h>
@@ -307,7 +305,6 @@ struct _zend_mm_heap {
307305
} custom_heap;
308306
HashTable *tracked_allocs;
309307
#endif
310-
pid_t pid;
311308
zend_random_bytes_insecure_state rand_state;
312309
};
313310

@@ -1300,15 +1297,20 @@ static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend
13001297
#endif
13011298
}
13021299

1303-
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot)
1300+
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, zend_mm_free_slot *slot)
13041301
{
13051302
#ifdef WORDS_BIGENDIAN
1306-
return (zend_mm_free_slot*)((uintptr_t)slot ^ heap->shadow_key);
1303+
return (zend_mm_free_slot*)((uintptr_t)slot ^ shadow_key);
13071304
#else
1308-
return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ heap->shadow_key));
1305+
return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ shadow_key));
13091306
#endif
13101307
}
13111308

1309+
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot)
1310+
{
1311+
return zend_mm_decode_free_slot_key(heap->shadow_key, slot);
1312+
}
1313+
13121314
static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot *slot, zend_mm_free_slot *next)
13131315
{
13141316
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE);
@@ -2017,6 +2019,30 @@ static void zend_mm_init_key(zend_mm_heap *heap)
20172019
zend_mm_refresh_key(heap);
20182020
}
20192021

2022+
static void zend_mm_refresh_key_child(zend_mm_heap *heap)
2023+
{
2024+
uintptr_t old_key = heap->shadow_key;
2025+
2026+
zend_mm_init_key(heap);
2027+
2028+
/* Update shadow pointers with new key */
2029+
for (int i = 0; i < ZEND_MM_BINS; i++) {
2030+
zend_mm_free_slot *slot = heap->free_slot[i];
2031+
if (!slot) {
2032+
continue;
2033+
}
2034+
zend_mm_free_slot *next;
2035+
while ((next = slot->next_free_slot)) {
2036+
zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, i);
2037+
if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow))) {
2038+
zend_mm_panic("zend_mm_heap corrupted");
2039+
}
2040+
zend_mm_set_next_free_slot(heap, i, slot, next);
2041+
slot = next;
2042+
}
2043+
}
2044+
}
2045+
20202046
static zend_mm_heap *zend_mm_init(void)
20212047
{
20222048
zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc_int(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
@@ -2065,7 +2091,6 @@ static zend_mm_heap *zend_mm_init(void)
20652091
heap->storage = NULL;
20662092
#endif
20672093
heap->huge_list = NULL;
2068-
heap->pid = getpid();
20692094
return heap;
20702095
}
20712096

@@ -2511,13 +2536,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
25112536
p->free_map[0] = (1L << ZEND_MM_FIRST_PAGE) - 1;
25122537
p->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE);
25132538

2514-
pid_t pid = getpid();
2515-
if (heap->pid != pid) {
2516-
zend_mm_init_key(heap);
2517-
heap->pid = pid;
2518-
} else {
2519-
zend_mm_refresh_key(heap);
2520-
}
2539+
zend_mm_refresh_key(heap);
25212540
}
25222541
}
25232542

@@ -2924,6 +2943,11 @@ ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown)
29242943
zend_mm_shutdown(AG(mm_heap), full_shutdown, silent);
29252944
}
29262945

2946+
ZEND_API void refresh_memory_manager(void)
2947+
{
2948+
zend_mm_refresh_key_child(AG(mm_heap));
2949+
}
2950+
29272951
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
29282952
{
29292953
fprintf(stderr, "Out of memory\n");
@@ -3268,7 +3292,6 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
32683292
memcpy(storage->data, data, data_size);
32693293
}
32703294
heap->storage = storage;
3271-
heap->pid = getpid();
32723295
return heap;
32733296
#else
32743297
return NULL;

Zend/zend_alloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ ZEND_API bool zend_alloc_in_memory_limit_error_reporting(void);
220220

221221
ZEND_API void start_memory_manager(void);
222222
ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown);
223+
ZEND_API void refresh_memory_manager(void);
223224
ZEND_API bool is_zend_mm(void);
224225
ZEND_API bool is_zend_ptr(const void *ptr);
225226

ext/pcntl/pcntl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ PHP_FUNCTION(pcntl_fork)
292292

293293
}
294294
} else if (id == 0) {
295+
php_child_init();
295296
zend_max_execution_timer_init();
296297
}
297298

main/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,11 @@ static void sigchld_handler(int apar)
17971797
/* }}} */
17981798
#endif
17991799

1800+
PHPAPI void php_child_init(void)
1801+
{
1802+
refresh_memory_manager();
1803+
}
1804+
18001805
/* {{{ php_request_startup */
18011806
zend_result php_request_startup(void)
18021807
{

main/php_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ PHPAPI unsigned int php_version_id(void);
4242
PHPAPI char *php_get_version(sapi_module_struct *sapi_module);
4343
PHPAPI void php_print_version(sapi_module_struct *sapi_module);
4444

45+
PHPAPI void php_child_init(void);
4546
PHPAPI zend_result php_request_startup(void);
4647
PHPAPI void php_request_shutdown(void *dummy);
4748
PHPAPI zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_module);

sapi/apache2handler/sapi_apache2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ zend_first_try {
751751
static void php_apache_child_init(apr_pool_t *pchild, server_rec *s)
752752
{
753753
apr_pool_cleanup_register(pchild, NULL, php_apache_child_shutdown, apr_pool_cleanup_null);
754+
php_child_init();
754755
}
755756

756757
#ifdef ZEND_SIGNALS

sapi/cgi/cgi_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,8 @@ consult the installation file that came with this distribution, or visit \n\
20432043
*/
20442044
parent = 0;
20452045

2046+
php_child_init();
2047+
20462048
/* don't catch our signals */
20472049
sigaction(SIGTERM, &old_term, 0);
20482050
sigaction(SIGQUIT, &old_quit, 0);

sapi/cli/php_cli_server.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,6 +2528,7 @@ static void php_cli_server_startup_workers(void) {
25282528
#if defined(HAVE_PRCTL) || defined(HAVE_PROCCTL)
25292529
php_cli_server_worker_install_pdeathsig();
25302530
#endif
2531+
php_child_init();
25312532
return;
25322533
} else {
25332534
php_cli_server_workers[php_cli_server_worker] = pid;

sapi/fpm/fpm/fpm_php.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ int fpm_php_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
239239
limit_extensions = wp->limit_extensions;
240240
wp->limit_extensions = NULL;
241241
}
242+
243+
php_child_init();
244+
242245
return 0;
243246
}
244247
/* }}} */

0 commit comments

Comments
 (0)