Skip to content

Commit 4da4610

Browse files
committed
Fix memory leaks in ext/sodium on failure of some functions
Infallible in practice right now, but should be fixed as infallible today does not mean infallible tomorrow: - sodium_crypto_sign_publickey_from_secretkey - sodium_crypto_kx_seed_keypair - sodium_crypto_kx_keypair - sodium_crypto_auth - sodium_crypto_sign_ed25519_sk_to_curve25519 - sodium_pad Fallible today: - sodium_crypto_sign_ed25519_pk_to_curve25519 Closes phpGH-14309.
1 parent 04c9749 commit 4da4610

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ PHP NEWS
66
. Fixed bug GH-14267 (opcache.jit=off does not allow enabling JIT at runtime).
77
(ilutov)
88

9+
- Sodium:
10+
. Fix memory leaks in ext/sodium on failure of some functions. (nielsdos)
11+
912
- SPL:
1013
. Fixed bug GH-14290 (Member access within null pointer in extension spl).
1114
(nielsdos)

ext/sodium/libsodium.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ PHP_FUNCTION(sodium_crypto_sign_publickey_from_secretkey)
992992

993993
if (crypto_sign_ed25519_sk_to_pk((unsigned char *) ZSTR_VAL(publickey),
994994
(const unsigned char *) secretkey) != 0) {
995+
zend_string_efree(publickey);
995996
zend_throw_exception(sodium_exception_ce,
996997
"internal error", 0);
997998
RETURN_THROWS();
@@ -2475,6 +2476,7 @@ PHP_FUNCTION(sodium_crypto_kx_seed_keypair)
24752476
crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
24762477
seed, crypto_kx_SEEDBYTES, NULL, 0);
24772478
if (crypto_scalarmult_base(pk, sk) != 0) {
2479+
zend_string_efree(keypair);
24782480
zend_throw_exception(sodium_exception_ce, "internal error", 0);
24792481
RETURN_THROWS();
24802482
}
@@ -2496,6 +2498,7 @@ PHP_FUNCTION(sodium_crypto_kx_keypair)
24962498
pk = sk + crypto_kx_SECRETKEYBYTES;
24972499
randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
24982500
if (crypto_scalarmult_base(pk, sk) != 0) {
2501+
zend_string_efree(keypair);
24992502
zend_throw_exception(sodium_exception_ce, "internal error", 0);
25002503
RETURN_THROWS();
25012504
}
@@ -2672,6 +2675,7 @@ PHP_FUNCTION(sodium_crypto_auth)
26722675
if (crypto_auth((unsigned char *) ZSTR_VAL(mac),
26732676
(const unsigned char *) msg, msg_len,
26742677
(const unsigned char *) key) != 0) {
2678+
zend_string_efree(mac);
26752679
zend_throw_exception(sodium_exception_ce, "internal error", 0);
26762680
RETURN_THROWS();
26772681
}
@@ -2731,6 +2735,7 @@ PHP_FUNCTION(sodium_crypto_sign_ed25519_sk_to_curve25519)
27312735

27322736
if (crypto_sign_ed25519_sk_to_curve25519((unsigned char *) ZSTR_VAL(ecdhkey),
27332737
(const unsigned char *) eddsakey) != 0) {
2738+
zend_string_efree(ecdhkey);
27342739
zend_throw_exception(sodium_exception_ce, "conversion failed", 0);
27352740
RETURN_THROWS();
27362741
}
@@ -2758,6 +2763,7 @@ PHP_FUNCTION(sodium_crypto_sign_ed25519_pk_to_curve25519)
27582763

27592764
if (crypto_sign_ed25519_pk_to_curve25519((unsigned char *) ZSTR_VAL(ecdhkey),
27602765
(const unsigned char *) eddsakey) != 0) {
2766+
zend_string_efree(ecdhkey);
27612767
zend_throw_exception(sodium_exception_ce, "conversion failed", 0);
27622768
RETURN_THROWS();
27632769
}
@@ -3036,6 +3042,7 @@ PHP_FUNCTION(sodium_pad)
30363042
#if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6)
30373043
if (sodium_pad(NULL, (unsigned char *) ZSTR_VAL(padded), unpadded_len,
30383044
(size_t) blocksize, xpadded_len + 1U) != 0) {
3045+
zend_string_efree(padded);
30393046
zend_throw_exception(sodium_exception_ce, "internal error", 0);
30403047
RETURN_THROWS();
30413048
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Memory leak on sodium_crypto_sign_ed25519_pk_to_curve25519() failure
3+
--EXTENSIONS--
4+
sodium
5+
--FILE--
6+
<?php
7+
8+
try {
9+
sodium_crypto_sign_ed25519_pk_to_curve25519(str_repeat("\x00", SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES));
10+
} catch (SodiumException $e) {
11+
echo $e->getMessage();
12+
}
13+
14+
?>
15+
--EXPECT--
16+
conversion failed

0 commit comments

Comments
 (0)