Skip to content

ext/openssl: Use zend_string_release on sigbuf in openssl_sign error path#64

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/openssl-ss006-efree-sigbuf
Closed

ext/openssl: Use zend_string_release on sigbuf in openssl_sign error path#64
iliaal wants to merge 1 commit into
PHP-8.4from
fix/openssl-ss006-efree-sigbuf

Conversation

@iliaal
Copy link
Copy Markdown
Owner

@iliaal iliaal commented May 13, 2026

sigbuf is a zend_string allocated via zend_string_alloc. The error branch called efree(sigbuf), which happens to release the underlying memory because zend_string_alloc is currently implemented on top of emalloc, but efree is the raw-memory API and skips the refcount and interned-string checks that zend_string_release performs. The match for zend_string_alloc is zend_string_release; every other release site in this file uses that pair.

Replace efree(sigbuf) with a NULL-guarded zend_string_release(). The NULL guard preserves the existing short-circuit behavior where the short-circuit fails before zend_string_alloc and sigbuf stays NULL; the release covers the path where zend_string_alloc succeeded but the following EVP_DigestSign/EVP_SignFinal failed.

Existing openssl_sign_basic, openssl_sign_invalid_algorithm, and bug81713 tests exercise the NULL-sigbuf branch and continue to pass under this patch.

…path

sigbuf is a zend_string allocated via zend_string_alloc. The error
branch called efree(sigbuf), which happens to release the underlying
memory because zend_string_alloc is currently implemented on top of
emalloc, but efree is the raw-memory API and skips the refcount and
interned-string checks that zend_string_release performs. The match for
zend_string_alloc is zend_string_release; every other release site in
this file uses that pair.

Replace efree(sigbuf) with a NULL-guarded zend_string_release(). The
NULL guard preserves the existing short-circuit behavior where the
short-circuit fails before zend_string_alloc and sigbuf stays NULL;
the release covers the path where zend_string_alloc succeeded but the
following EVP_DigestSign/EVP_SignFinal failed.

Existing openssl_sign_basic, openssl_sign_invalid_algorithm, and
bug81713 tests exercise the NULL-sigbuf branch and continue to pass.
@iliaal
Copy link
Copy Markdown
Owner Author

iliaal commented May 13, 2026

Closing without promotion. Reviewed the original code more carefully: efree(NULL) is safe in standard PHP MM (the page_offset == 0 branch of zend_mm_free_heap has an explicit NULL guard), and efree(sigbuf) on a fresh zend_string_alloc() pointer releases the right bytes because the zend_string header IS the allocation base. No leak, no crash; the change was API hygiene at best, and the NULL guard only became necessary because zend_string_release() (unlike efree()) dereferences without checking.

@iliaal iliaal closed this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant