Skip to content

Commit 2609164

Browse files
committed
Refresh zend_mm shadow key on fork
1 parent 747ecce commit 2609164

File tree

9 files changed

+54
-15
lines changed

9 files changed

+54
-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>
@@ -317,7 +315,6 @@ struct _zend_mm_heap {
317315
} debug;
318316
};
319317
#endif
320-
pid_t pid;
321318
zend_random_bytes_insecure_state rand_state;
322319
};
323320

@@ -1310,15 +1307,20 @@ static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend
13101307
#endif
13111308
}
13121309

1313-
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot)
1310+
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, zend_mm_free_slot *slot)
13141311
{
13151312
#ifdef WORDS_BIGENDIAN
1316-
return (zend_mm_free_slot*)((uintptr_t)slot ^ heap->shadow_key);
1313+
return (zend_mm_free_slot*)((uintptr_t)slot ^ shadow_key);
13171314
#else
1318-
return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ heap->shadow_key));
1315+
return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ shadow_key));
13191316
#endif
13201317
}
13211318

1319+
static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot)
1320+
{
1321+
return zend_mm_decode_free_slot_key(heap->shadow_key, slot);
1322+
}
1323+
13221324
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)
13231325
{
13241326
ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE);
@@ -2027,6 +2029,30 @@ static void zend_mm_init_key(zend_mm_heap *heap)
20272029
zend_mm_refresh_key(heap);
20282030
}
20292031

2032+
static void zend_mm_refresh_key_child(zend_mm_heap *heap)
2033+
{
2034+
uintptr_t old_key = heap->shadow_key;
2035+
2036+
zend_mm_init_key(heap);
2037+
2038+
/* Update shadow pointers with new key */
2039+
for (int i = 0; i < ZEND_MM_BINS; i++) {
2040+
zend_mm_free_slot *slot = heap->free_slot[i];
2041+
if (!slot) {
2042+
continue;
2043+
}
2044+
zend_mm_free_slot *next;
2045+
while ((next = slot->next_free_slot)) {
2046+
zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, i);
2047+
if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow))) {
2048+
zend_mm_panic("zend_mm_heap corrupted");
2049+
}
2050+
zend_mm_set_next_free_slot(heap, i, slot, next);
2051+
slot = next;
2052+
}
2053+
}
2054+
}
2055+
20302056
static zend_mm_heap *zend_mm_init(void)
20312057
{
20322058
zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc_int(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
@@ -2075,7 +2101,6 @@ static zend_mm_heap *zend_mm_init(void)
20752101
heap->storage = NULL;
20762102
#endif
20772103
heap->huge_list = NULL;
2078-
heap->pid = getpid();
20792104
return heap;
20802105
}
20812106

@@ -2535,13 +2560,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
25352560
p->free_map[0] = (1L << ZEND_MM_FIRST_PAGE) - 1;
25362561
p->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE);
25372562

2538-
pid_t pid = getpid();
2539-
if (heap->pid != pid) {
2540-
zend_mm_init_key(heap);
2541-
heap->pid = pid;
2542-
} else {
2543-
zend_mm_refresh_key(heap);
2544-
}
2563+
zend_mm_refresh_key(heap);
25452564
}
25462565
}
25472566

@@ -2949,6 +2968,11 @@ ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown)
29492968
zend_mm_shutdown(AG(mm_heap), full_shutdown, silent);
29502969
}
29512970

2971+
ZEND_API void refresh_memory_manager(void)
2972+
{
2973+
zend_mm_refresh_key_child(AG(mm_heap));
2974+
}
2975+
29522976
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
29532977
{
29542978
fprintf(stderr, "Out of memory\n");
@@ -3506,7 +3530,6 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
35063530
memcpy(storage->data, data, data_size);
35073531
}
35083532
heap->storage = storage;
3509-
heap->pid = getpid();
35103533
return heap;
35113534
#else
35123535
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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "php_signal.h"
3333
#include "php_ticks.h"
3434
#include "zend_fibers.h"
35+
#include "main/php_main.h"
3536

3637
#if defined(HAVE_GETPRIORITY) || defined(HAVE_SETPRIORITY) || defined(HAVE_WAIT3)
3738
#include <sys/wait.h>
@@ -297,6 +298,7 @@ PHP_FUNCTION(pcntl_fork)
297298

298299
}
299300
} else if (id == 0) {
301+
php_child_init();
300302
zend_max_execution_timer_init();
301303
}
302304

main/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,11 @@ static void sigchld_handler(int apar)
18161816
/* }}} */
18171817
#endif
18181818

1819+
PHPAPI void php_child_init(void)
1820+
{
1821+
refresh_memory_manager();
1822+
}
1823+
18191824
/* {{{ php_request_startup */
18201825
zend_result php_request_startup(void)
18211826
{

main/php_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ ZEND_ATTRIBUTE_CONST PHPAPI const char *php_build_provider(void);
4949
PHPAPI char *php_get_version(sapi_module_struct *sapi_module);
5050
PHPAPI void php_print_version(sapi_module_struct *sapi_module);
5151

52+
PHPAPI void php_child_init(void);
5253
PHPAPI zend_result php_request_startup(void);
5354
PHPAPI void php_request_shutdown(void *dummy);
5455
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
@@ -752,6 +752,7 @@ zend_first_try {
752752
static void php_apache_child_init(apr_pool_t *pchild, server_rec *s)
753753
{
754754
apr_pool_cleanup_register(pchild, NULL, php_apache_child_shutdown, apr_pool_cleanup_null);
755+
php_child_init();
755756
}
756757

757758
#ifdef ZEND_SIGNALS

sapi/cgi/cgi_main.c

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

2044+
php_child_init();
2045+
20442046
/* don't catch our signals */
20452047
sigaction(SIGTERM, &old_term, 0);
20462048
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
@@ -2530,6 +2530,7 @@ static void php_cli_server_startup_workers(void) {
25302530
#if defined(HAVE_PRCTL) || defined(HAVE_PROCCTL)
25312531
php_cli_server_worker_install_pdeathsig();
25322532
#endif
2533+
php_child_init();
25332534
return;
25342535
} else {
25352536
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
@@ -253,6 +253,9 @@ int fpm_php_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
253253
limit_extensions = wp->limit_extensions;
254254
wp->limit_extensions = NULL;
255255
}
256+
257+
php_child_init();
258+
256259
return 0;
257260
}
258261
/* }}} */

0 commit comments

Comments
 (0)