Commit 68d605fa924 for php.net
commit 68d605fa924a34247aa800f06ab86a7b60b423ce
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sun Jun 21 08:10:09 2026 -0400
Fix OOB read in opcache POSIX largepage page-size selection
create_segments() under HAVE_SHM_CREATE_LARGEPAGE stored the int return
of getpagesizes() in a size_t and iterated with a size_t counter. On the
getpagesizes() error return (-1) the size_t became SIZE_MAX, passing the
> 0 guard, and the unsigned loop counter made i >= 0 always true, so the
loop ran from a huge index and read far outside the 3-element
shared_segment_sindexes array; even on success, if no returned page size
divided requested_size the counter wrapped past 0. Capture the result in
a signed int and iterate signed so the error return is rejected and the
loop terminates.
Closes GH-22429
diff --git a/ext/opcache/shared_alloc_posix.c b/ext/opcache/shared_alloc_posix.c
index 3f1e097fe97..aa474729594 100644
--- a/ext/opcache/shared_alloc_posix.c
+++ b/ext/opcache/shared_alloc_posix.c
@@ -51,9 +51,10 @@ static int create_segments(size_t requested_size, zend_shared_segment_posix ***s
* only then amd64/i386/arm64 and perharps risc64*
* archs are on interest here.
*/
- size_t i, shared_segment_sizes = 0, shared_segment_lg_index = 0;
+ size_t shared_segment_lg_index = 0;
size_t shared_segment_sindexes[3] = {0};
const size_t entries = sizeof(shared_segment_sindexes) / sizeof(shared_segment_sindexes[0]);
+ int i, shared_segment_sizes;
shared_segment_sizes = getpagesizes(shared_segment_sindexes, entries);