Skip to content

Commit 68e6c15

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix ASLR related invalid opline handler issues
2 parents 7dec7a1 + 8ba10b8 commit 68e6c15

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

ext/opcache/shared_alloc_win32.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ZendAccelerator.h"
2323
#include "zend_shared_alloc.h"
2424
#include "zend_accelerator_util_funcs.h"
25+
#include "zend_execute.h"
2526
#include "tsrm_win32.h"
2627
#include "win32/winutil.h"
2728
#include <winbase.h>
@@ -133,6 +134,8 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
133134
char *mmap_base_file = get_mmap_base_file();
134135
FILE *fp = fopen(mmap_base_file, "r");
135136
MEMORY_BASIC_INFORMATION info;
137+
void *execute_ex_base;
138+
int execute_ex_moved;
136139

137140
if (!fp) {
138141
err = GetLastError();
@@ -148,15 +151,25 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
148151
fclose(fp);
149152
return ALLOC_FAILURE;
150153
}
154+
if (!fscanf(fp, "%p", &execute_ex_base)) {
155+
err = GetLastError();
156+
zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read execute_ex base address", err);
157+
*error_in="read execute_ex base";
158+
fclose(fp);
159+
return ALLOC_FAILURE;
160+
}
151161
fclose(fp);
152162

153163
if (0 > win32_utime(mmap_base_file, NULL)) {
154164
err = GetLastError();
155165
zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err);
156166
}
157167

158-
/* Check if the requested address space is free */
159-
if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 ||
168+
execute_ex_moved = (void *)execute_ex != execute_ex_base;
169+
170+
/* Check if execute_ex is at the same address and if the requested address space is free */
171+
if (execute_ex_moved ||
172+
VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 ||
160173
info.State != MEM_FREE ||
161174
info.RegionSize < requested_size) {
162175
#if ENABLE_FILE_CACHE_FALLBACK
@@ -165,8 +178,13 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
165178

166179
wanted_mb_save = (size_t)wanted_mapping_base;
167180

168-
err = ERROR_INVALID_ADDRESS;
169-
zend_win_error_message(ACCEL_LOG_WARNING, "Base address marks unusable memory region (fall-back to file cache)", err);
181+
if (execute_ex_moved) {
182+
err = ERROR_INVALID_ADDRESS;
183+
zend_win_error_message(ACCEL_LOG_WARNING, "Opcode handlers are unusable due to ASLR (fall-back to file cache)", err);
184+
} else {
185+
err = ERROR_INVALID_ADDRESS;
186+
zend_win_error_message(ACCEL_LOG_WARNING, "Base address marks unusable memory region (fall-back to file cache)", err);
187+
}
170188

171189
pre_size = ZEND_ALIGNED_SIZE(sizeof(zend_smm_shared_globals)) + ZEND_ALIGNED_SIZE(sizeof(zend_shared_segment)) + ZEND_ALIGNED_SIZE(sizeof(void *)) + ZEND_ALIGNED_SIZE(sizeof(int));
172190
/* Map only part of SHM to have access opcache shared globals */
@@ -181,10 +199,15 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
181199
return ALLOC_FALLBACK;
182200
}
183201
#endif
184-
err = ERROR_INVALID_ADDRESS;
185-
zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region. Please setup opcache.file_cache and opcache.file_cache_fallback directives for more convenient Opcache usage", err);
202+
if (execute_ex_moved) {
203+
err = ERROR_INVALID_ADDRESS;
204+
zend_win_error_message(ACCEL_LOG_FATAL, "Opcode handlers are unusable due to ASLR. Please setup opcache.file_cache and opcache.file_cache_fallback directives for more convenient Opcache usage", err);
205+
} else {
206+
err = ERROR_INVALID_ADDRESS;
207+
zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region. Please setup opcache.file_cache and opcache.file_cache_fallback directives for more convenient Opcache usage", err);
208+
}
186209
return ALLOC_FAILURE;
187-
}
210+
}
188211

189212
mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS|FILE_MAP_EXECUTE, 0, 0, 0, wanted_mapping_base);
190213

@@ -324,6 +347,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_
324347
return ALLOC_FAILURE;
325348
} else {
326349
char *mmap_base_file;
350+
void *execute_ex_base = (void *)execute_ex;
327351
FILE *fp;
328352
DWORD old;
329353

@@ -342,6 +366,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_
342366
return ALLOC_FAILURE;
343367
}
344368
fprintf(fp, "%p\n", mapping_base);
369+
fprintf(fp, "%p\n", execute_ex_base);
345370
fclose(fp);
346371
}
347372

0 commit comments

Comments
 (0)