From 0541099f3301e5a09ec8c1b37b3df6fbe6604900 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 21 Jun 2026 08:10:09 -0400 Subject: [PATCH] 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. --- ext/opcache/shared_alloc_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/opcache/shared_alloc_posix.c b/ext/opcache/shared_alloc_posix.c index 3f1e097fe97c..aa474729594b 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);