From 09cccab30d53614bb826e4390ad23ad7451b6d6c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 29 May 2026 21:44:14 +0100 Subject: [PATCH] ext/openssl: openssl_encrypt() zend mm heap overflow on AES-WRAP-PAD mode. Fix #22186 close GH-22187 (cherry picked from commit cbc0489126a7682796aad1e5fb4e51de74af162c) (cherry picked from commit 95e9851111d249e43948b76663cff1baeb5e758d) (cherry picked from commit 2a73e91a9f9136fbbfcc9177573b6af71e3d5dce) (cherry picked from commit e058b01e1bd23421a425cffae9f458b0fa8db222) --- NEWS | 6 ++++++ ext/openssl/openssl.c | 15 ++++++++++++++- ext/openssl/tests/gh22186.phpt | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 ext/openssl/tests/gh22186.phpt diff --git a/NEWS b/NEWS index fe425c4f5c..fa18e93cb3 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,12 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +Backported from 8.2.32 + +- OpenSSL: + . Fixed bug GH-22187 (Memory corruption (zend_mm_heap corrupted) in + openssl_encrypt with AES-WRAP-PAD). (David Carlier) + Backported from 8.2.31 - FPM: diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 2dc8eb3333..da9da1454e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -6566,6 +6566,7 @@ static int php_openssl_cipher_update(const EVP_CIPHER *cipher_type, char *aad, size_t aad_len, int enc) /* {{{ */ { int i = 0; + size_t outlen = data_len + EVP_CIPHER_block_size(cipher_type); if (mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, NULL, (int)data_len)) { php_openssl_store_errors(); @@ -6579,7 +6580,19 @@ static int php_openssl_cipher_update(const EVP_CIPHER *cipher_type, return FAILURE; } - *poutbuf = zend_string_alloc((int)data_len + EVP_CIPHER_block_size(cipher_type), 0); +#ifdef EVP_CIPH_WRAP_MODE + if ((EVP_CIPHER_mode(cipher_type)) == EVP_CIPH_WRAP_MODE) { + /* + * RFC 5649 wrap-with-padding rounds the input up to the block size + * and prepends an integrity block, we reserve one extra block. + * See EVP_EncryptUpdate(3): wrap mode may write up to + * inl + cipher_block_size bytes. + */ + outlen += EVP_CIPHER_block_size(cipher_type); + } +#endif + + *poutbuf = zend_string_alloc(outlen, 0); if (!EVP_CipherUpdate(cipher_ctx, (unsigned char*)ZSTR_VAL(*poutbuf), &i, (unsigned char *)data, (int)data_len)) { diff --git a/ext/openssl/tests/gh22186.phpt b/ext/openssl/tests/gh22186.phpt new file mode 100644 index 0000000000..8f28e6c45b --- /dev/null +++ b/ext/openssl/tests/gh22186.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-22186 (Heap buffer overflow in openssl_encrypt with AES-WRAP-PAD) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +done -- 2.54.0