Skip to content

Commit 2d030f5

Browse files
committed
Fix the JIT buffer relocation failure at the corner case
Avoid missing possible candidates due to the large address range of the free segment. Eg,  48000000-49400000 r-xs 08000000 00:0f 39322841               segment1 7ffff2ec8000-7ffff2f49000 rw-p 00000000 00:00 0              segment2 7ffff6fae000-7ffff735c000 r-xp 00200000 08:02 11538515       /usr/local/sbin/php-fpm original code will miss the opportunity between [7ffff2ec** - 7ffff2ec8000]. Fix issue #11265. Signed-off-by: Long, Tao <[email protected]> Signed-off-by: Dmitry Stogov <[email protected]>
1 parent 8d0345d commit 2d030f5

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

ext/opcache/shared_alloc_mmap.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,13 @@ static void *find_prefered_mmap_base(size_t requested_size)
6767
while (fgets(buffer, MAXPATHLEN, f) && sscanf(buffer, "%lx-%lx", &start, &end) == 2) {
6868
if ((uintptr_t)execute_ex >= start) {
6969
/* the current segment lays before PHP .text segment or PHP .text segment itself */
70+
/*Search for candidates at the end of the free segment near the .text segment
71+
to prevent candidates from being missed due to large hole*/
7072
if (last_free_addr + requested_size <= start) {
71-
last_candidate = last_free_addr;
73+
last_candidate = ZEND_MM_ALIGNED_SIZE_EX(start - requested_size, huge_page_size);
74+
if (last_candidate + requested_size > start) {
75+
last_candidate -= huge_page_size;
76+
}
7277
}
7378
if ((uintptr_t)execute_ex < end) {
7479
/* the current segment is PHP .text segment itself */
@@ -117,7 +122,10 @@ static void *find_prefered_mmap_base(size_t requested_size)
117122
if ((uintptr_t)execute_ex >= e_start) {
118123
/* the current segment lays before PHP .text segment or PHP .text segment itself */
119124
if (last_free_addr + requested_size <= e_start) {
120-
last_candidate = last_free_addr;
125+
last_candidate = ZEND_MM_ALIGNED_SIZE_EX(e_start - requested_size, huge_page_size);
126+
if (last_candidate + requested_size > e_start) {
127+
last_candidate -= huge_page_size;
128+
}
121129
}
122130
if ((uintptr_t)execute_ex < e_end) {
123131
/* the current segment is PHP .text segment itself */

0 commit comments

Comments
 (0)