From 4924be47859aca7283a1ad00020d54d282e7ae6f Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 21 Jul 2021 13:55:13 +0200 Subject: [PATCH] Fix #74960: Heap buffer overflow via str_repeat Trying to allocate a `zend_string` with a length only slighty smaller than `SIZE_MAX` causes an integer overflow, so callers may need to check that explicitly. To make that easy in a portable way, we introduce `ZSTR_MAX_LEN`. --- Zend/zend_operators.c | 2 +- Zend/zend_string.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 596581270b047..031894755c8eb 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1882,7 +1882,7 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / size_t result_len = op1_len + op2_len; zend_string *result_str; - if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { + if (UNEXPECTED(op1_len > ZSTR_MAX_LEN - op2_len)) { zend_throw_error(NULL, "String size overflow"); zval_ptr_dtor_str(&op1_copy); zval_ptr_dtor_str(&op2_copy); diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 96169d9a277b0..d90d2e06d38ff 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -75,6 +75,8 @@ END_EXTERN_C() #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1) +#define ZSTR_MAX_LEN (SIZE_MAX - ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1)) + #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \ (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \ GC_SET_REFCOUNT(str, 1); \