From 34b981dd0eb658b4db1d4168722bc661d442debe Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 20 Jul 2020 13:47:43 +0200 Subject: [PATCH 1/2] Fix #73060: php failed with error after temp folder cleaned up Instead of storing the mapping base address and the address of `execute_ex()` in a separate file in the temporary folder, we store them right at the beginning of the memory mapping. --- ext/opcache/shared_alloc_win32.c | 69 +++++--------------------------- 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index 3ae65382f4f7e..c952b71434f4f 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -93,28 +93,6 @@ static char *create_name_with_username(char *name) return newname; } -static char *get_mmap_base_file(void) -{ - static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@") + 1 + 32 + 21]; - char *uname; - int l; - - uname = php_win32_get_username(); - if (!uname) { - return NULL; - } - GetTempPath(MAXPATHLEN, windir); - l = strlen(windir); - if ('\\' == windir[l-1]) { - l--; - } - snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s@%.20s@%.32s", ACCEL_FILEMAP_BASE, uname, sapi_module.name, ZCG(system_id)); - - free(uname); - - return windir; -} - void zend_shared_alloc_create_lock(void) { memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME)); @@ -143,39 +121,20 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in) { int err; void *wanted_mapping_base; - char *mmap_base_file = get_mmap_base_file(); - FILE *fp = fopen(mmap_base_file, "r"); MEMORY_BASIC_INFORMATION info; void *execute_ex_base; int execute_ex_moved; - if (!fp) { - err = GetLastError(); - zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err); - zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open base address file", err); - *error_in="fopen"; - return ALLOC_FAILURE; - } - if (!fscanf(fp, "%p", &wanted_mapping_base)) { + mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 2 * sizeof(void*), NULL); + if (mapping_base == NULL) { err = GetLastError(); zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read base address", err); *error_in="read mapping base"; - fclose(fp); return ALLOC_FAILURE; } - if (!fscanf(fp, "%p", &execute_ex_base)) { - err = GetLastError(); - zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read execute_ex base address", err); - *error_in="read execute_ex base"; - fclose(fp); - return ALLOC_FAILURE; - } - fclose(fp); - - if (0 > win32_utime(mmap_base_file, NULL)) { - err = GetLastError(); - zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err); - } + wanted_mapping_base = ((void**)mapping_base)[0]; + execute_ex_base = ((void**)mapping_base)[1]; + UnmapViewOfFile(mapping_base); execute_ex_moved = (void *)execute_ex != execute_ex_base; @@ -231,7 +190,7 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in) } return ALLOC_FAIL_MAPPING; } - smm_shared_globals = (zend_smm_shared_globals *) mapping_base; + smm_shared_globals = (zend_smm_shared_globals *) ((char*)mapping_base + 2 * sizeof(void*)); return SUCCESSFULLY_REATTACHED; } @@ -349,20 +308,10 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ *error_in = "MapViewOfFile"; return ALLOC_FAILURE; } else { - char *mmap_base_file = get_mmap_base_file(); - void *execute_ex_base = (void *)execute_ex; - FILE *fp = fopen(mmap_base_file, "w"); - if (!fp) { - err = GetLastError(); - zend_shared_alloc_unlock_win32(); - zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err); - zend_win_error_message(ACCEL_LOG_FATAL, "Unable to write base address", err); - return ALLOC_FAILURE; + ((void**)mapping_base)[0] = mapping_base; + ((void**)mapping_base)[1] = (void*)execute_ex; + ((char*)shared_segment->p) += 2 * sizeof(void*); } - fprintf(fp, "%p\n", mapping_base); - fprintf(fp, "%p\n", execute_ex_base); - fclose(fp); - } shared_segment->pos = 0; shared_segment->size = requested_size; From 4192256a0944bcb9e7a1cf7b6e1ab090411e0589 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 28 Jul 2020 14:40:04 +0200 Subject: [PATCH 2/2] Minor improvements --- ext/opcache/shared_alloc_win32.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index c952b71434f4f..26bf0539eace8 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -31,10 +31,11 @@ #define ACCEL_FILEMAP_NAME "ZendOPcache.SharedMemoryArea" #define ACCEL_MUTEX_NAME "ZendOPcache.SharedMemoryMutex" -#define ACCEL_FILEMAP_BASE_DEFAULT 0x01000000 -#define ACCEL_FILEMAP_BASE "ZendOPcache.MemoryBase" #define ACCEL_EVENT_SOURCE "Zend OPcache" +/* address of mapping base and address of execute_ex */ +#define ACCEL_BASE_POINTER_SIZE (2 * sizeof(void*)) + static HANDLE memfile = NULL, memory_mutex = NULL; static void *mapping_base; @@ -125,7 +126,7 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in) void *execute_ex_base; int execute_ex_moved; - mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 2 * sizeof(void*), NULL); + mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, ACCEL_BASE_POINTER_SIZE, NULL); if (mapping_base == NULL) { err = GetLastError(); zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read base address", err); @@ -190,7 +191,7 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in) } return ALLOC_FAIL_MAPPING; } - smm_shared_globals = (zend_smm_shared_globals *) ((char*)mapping_base + 2 * sizeof(void*)); + smm_shared_globals = (zend_smm_shared_globals *) ((char*)mapping_base + ACCEL_BASE_POINTER_SIZE); return SUCCESSFULLY_REATTACHED; } @@ -310,8 +311,8 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ } else { ((void**)mapping_base)[0] = mapping_base; ((void**)mapping_base)[1] = (void*)execute_ex; - ((char*)shared_segment->p) += 2 * sizeof(void*); - } + ((char*)shared_segment->p) += ACCEL_BASE_POINTER_SIZE; + } shared_segment->pos = 0; shared_segment->size = requested_size;