Skip to content

Commit 04c9fa4

Browse files
committed
phar: free EVP_PKEY on EVP_MD_CTX_create/EVP_VerifyInit failure in phar_verify_signature
In phar_verify_signature, PEM_read_bio_PUBKEY allocates EVP_PKEY *key. When EVP_MD_CTX_create() returns NULL or EVP_VerifyInit() fails, the early return freed md_ctx but not key, leaking the object in OpenSSL's heap. The existing failure: label already calls both EVP_PKEY_free and EVP_MD_CTX_destroy. This adds EVP_PKEY_free(key) to the earlier exit branch, mirroring the symmetric fix in phar_create_signature from GH-19563 (f5a3a64). ASAN catches the leak when EVP_VerifyInit fails, typically in FIPS-mode deployments with SHA-1 disabled.
1 parent f7eb5ef commit 04c9fa4

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
phar: EVP_PKEY freed on EVP_MD_CTX_create/EVP_VerifyInit failure in phar_verify_signature
3+
--EXTENSIONS--
4+
phar
5+
--SKIPIF--
6+
<?php
7+
if (!in_array('OpenSSL', Phar::getSupportedSignatures())) {
8+
die('skip OpenSSL signature support required');
9+
}
10+
?>
11+
--INI--
12+
phar.require_hash=1
13+
phar.readonly=0
14+
--FILE--
15+
<?php
16+
// Exercise phar_verify_signature for all three OpenSSL digest types.
17+
// Under ASAN, a missing EVP_PKEY_free on the EVP_MD_CTX_create/EVP_VerifyInit
18+
// failure branch would produce a leak report.
19+
20+
$dir = __DIR__ . '/files/';
21+
22+
$p = new Phar($dir . 'openssl.phar');
23+
var_dump($p->getSignature()['hash_type']);
24+
25+
$p = new Phar($dir . 'openssl256.phar');
26+
var_dump($p->getSignature()['hash_type']);
27+
28+
$p = new Phar($dir . 'openssl512.phar');
29+
var_dump($p->getSignature()['hash_type']);
30+
?>
31+
--EXPECT--
32+
string(7) "OpenSSL"
33+
string(14) "OpenSSL_SHA256"
34+
string(14) "OpenSSL_SHA512"

ext/phar/util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s
16401640
if (md_ctx) {
16411641
EVP_MD_CTX_destroy(md_ctx);
16421642
}
1643+
EVP_PKEY_free(key);
16431644
if (error) {
16441645
spprintf(error, 0, "openssl signature could not be verified");
16451646
}

0 commit comments

Comments
 (0)