Skip to content

ext/openssl: openssl_encrypt() zend mm heap overflow on AES-WRAP-PAD …#22187

Closed
devnexen wants to merge 3 commits into
php:PHP-8.4from
devnexen:gh22186
Closed

ext/openssl: openssl_encrypt() zend mm heap overflow on AES-WRAP-PAD …#22187
devnexen wants to merge 3 commits into
php:PHP-8.4from
devnexen:gh22186

Conversation

@devnexen

Copy link
Copy Markdown
Member

…mode.

Fix #22186

@olegbaturin

olegbaturin commented May 29, 2026

Copy link
Copy Markdown

Is this for 8.4 only? 8.5, 8.3 are also affected,

@devnexen

devnexen commented May 29, 2026

Copy link
Copy Markdown
Member Author

it s the lowest branch (supported, 8.3 is EOL) it applies to, then we backport to upper branches

@devnexen devnexen marked this pull request as ready for review May 29, 2026 22:38
@devnexen devnexen requested a review from bukka as a code owner May 29, 2026 22:38
@devnexen devnexen requested a review from ndossche June 15, 2026 17:32

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix seems good. Please see my question.
This likely has security impact so it needs a backport.

Comment thread ext/openssl/openssl.c
const char *aad, size_t aad_len, int enc) /* {{{ */
{
int i = 0;
size_t outlen = data_len + EVP_CIPHER_block_size(cipher_type);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we risk an overflow of the sum? I also don't like how the data_len is downcasted to an int due to OpenSSL's API.
It means we need to cap data_len to INT_MAX (if that's not already the case).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No overflow risk. Both callers cap data_len to INT_MAX first (the PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN checks), so the worst case is INT_MAX + 2*block_size, which fits in size_t even on 32-bit. Same cap is what keeps the (int) casts safe.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also do not appreciate the downcasting much, but I guess that s the long (hi)story of openssl existence showing :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OKay, all good then

@devnexen devnexen closed this in 1692268 Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants