Skip to content

Commit 719236e

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix SELinux mprotect execheap error due to mem adjacent to heap
2 parents cd17917 + 7cf1a2a commit 719236e

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ PHP NEWS
2121
- Opcache:
2222
. Fixed oss-fuzz #64727 (JIT undefined array key warning may overwrite DIM
2323
with NULL when DIM is the same var as result). (ilutov)
24+
. Added workaround for SELinux mprotect execheap issue.
25+
See https://bugzilla.kernel.org/show_bug.cgi?id=218258. (ilutov)
2426

2527
07 Dec 2023, PHP 8.3.1RC1
2628

ext/opcache/shared_alloc_mmap.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ static void *find_prefered_mmap_base(size_t requested_size)
6565
}
6666

6767
while (fgets(buffer, MAXPATHLEN, f) && sscanf(buffer, "%lx-%lx", &start, &end) == 2) {
68+
/* Don't place the segment directly before or after the heap segment. Due to an selinux bug,
69+
* a segment directly preceding or following the heap is interpreted as heap memory, which
70+
* will result in an execheap violation for the JIT.
71+
* See https://bugzilla.kernel.org/show_bug.cgi?id=218258. */
72+
bool heap_segment = strstr(buffer, "[heap]") != NULL;
73+
if (heap_segment) {
74+
uintptr_t start_base = start & ~(huge_page_size - 1);
75+
if (last_free_addr + requested_size >= start_base) {
76+
last_free_addr = ZEND_MM_ALIGNED_SIZE_EX(end + huge_page_size, huge_page_size);
77+
continue;
78+
}
79+
}
6880
if ((uintptr_t)execute_ex >= start) {
6981
/* the current segment lays before PHP .text segment or PHP .text segment itself */
7082
/*Search for candidates at the end of the free segment near the .text segment
@@ -98,7 +110,9 @@ static void *find_prefered_mmap_base(size_t requested_size)
98110
}
99111
}
100112
last_free_addr = ZEND_MM_ALIGNED_SIZE_EX(end, huge_page_size);
101-
113+
if (heap_segment) {
114+
last_free_addr += huge_page_size;
115+
}
102116
}
103117
fclose(f);
104118
#elif defined(__FreeBSD__)

0 commit comments

Comments
 (0)