Commit c7ffb825aa1 for php.net
commit c7ffb825aa105bea7f6f32dea480fbe3dc49e009
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date: Mon Sep 21 21:06:14 2026 +0200
Fix OSS-Fuzz #5674034779193344: Read of uninitialized memory in is_cacheable_stream_path()
memcmp() will read inside the padding bytes of the zend_string, which
are not initialized. This is not exploitable because they're 8 padding
bytes and the length of "file://" and "phar://" is 7 so the mismatch
happens at the length-of-the-string index; returning non-0 anyway.
Closes GH-23830.
diff --git a/NEWS b/NEWS
index f76464756f3..95e545f919a 100644
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,8 @@ PHP NEWS
FCCs and inlining). (ndossche)
. Fixed bug GH-23693 (Tracing JIT produces wrong results for a guard on a
loop-invariant addition). (Ilia Alshanetsky)
+ . Fixed OSS-Fuzz #5674034779193344 (Read of uninitialized memory in
+ is_cacheable_stream_path()). (ndossche)
- PDO:
. Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 221cc55d9f6..8a285928cc0 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -195,10 +195,10 @@ static time_t zend_accel_get_time(void)
# define zend_accel_get_time() time(NULL)
#endif
-static inline bool is_cacheable_stream_path(const char *filename)
+static inline bool is_cacheable_stream_path(const zend_string *filename)
{
- return memcmp(filename, "file://", sizeof("file://") - 1) == 0 ||
- memcmp(filename, "phar://", sizeof("phar://") - 1) == 0;
+ return zend_string_starts_with_literal(filename, "file://") ||
+ zend_string_starts_with_literal(filename, "phar://");
}
/* O+ overrides PHP chdir() function and remembers the current working directory
@@ -1205,7 +1205,7 @@ zend_string *accel_make_persistent_key(zend_string *str)
if (IS_ABSOLUTE_PATH(path, path_length)) {
/* pass */
} else if (UNEXPECTED(php_is_stream_path(path))) {
- if (!is_cacheable_stream_path(path)) {
+ if (!is_cacheable_stream_path(str)) {
return NULL;
}
/* pass */
@@ -1903,7 +1903,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int
bool from_memory; /* if the script we've got is stored in SHM */
if (php_is_stream_path(ZSTR_VAL(file_handle->filename)) &&
- !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename))) {
+ !is_cacheable_stream_path(file_handle->filename)) {
return accelerator_orig_compile_file(file_handle, type);
}
@@ -2047,7 +2047,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
return accelerator_orig_compile_file(file_handle, type);
}
persistent_script = zend_accel_hash_find(&ZCSG(hash), key);
- } else if (UNEXPECTED(php_is_stream_path(ZSTR_VAL(file_handle->filename)) && !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename)))) {
+ } else if (UNEXPECTED(php_is_stream_path(ZSTR_VAL(file_handle->filename)) && !is_cacheable_stream_path(file_handle->filename))) {
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type);