1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
From 266174a6d36687b65cf90174f06af90b8b27c65f Mon Sep 17 00:00:00 2001
From: Francesco Rollo <eferollo@gmail.com>
Date: Thu, 24 Jul 2025 16:30:07 +0300
Subject: CVE-2025-8277: Fix memory leak of unused ephemeral key pair after
client's wrong KEX guess
Signed-off-by: Francesco Rollo <eferollo@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ccff22d3787c1355b3f0dcd09fe54d90acc55bf1)
---
src/dh_crypto.c | 5 +++++
src/dh_key.c | 5 +++++
src/ecdh_crypto.c | 11 +++++++++++
src/ecdh_gcrypt.c | 6 ++++++
src/ecdh_mbedcrypto.c | 6 ++++++
5 files changed, 33 insertions(+)
diff --git a/src/dh_crypto.c b/src/dh_crypto.c
index 4dd9b507e..cedfbc81a 100644
--- a/src/dh_crypto.c
+++ b/src/dh_crypto.c
@@ -407,6 +407,11 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
struct dh_ctx *ctx;
int rc;
+ /* Cleanup any previously allocated dh_ctx */
+ if (crypto->dh_ctx != NULL) {
+ ssh_dh_cleanup(crypto);
+ }
+
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return SSH_ERROR;
diff --git a/src/dh_key.c b/src/dh_key.c
index 20d24a316..d9743cebd 100644
--- a/src/dh_key.c
+++ b/src/dh_key.c
@@ -237,6 +237,11 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
struct dh_ctx *ctx = NULL;
int rc;
+ /* Cleanup any previously allocated dh_ctx */
+ if (crypto->dh_ctx != NULL) {
+ ssh_dh_cleanup(crypto);
+ }
+
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return SSH_ERROR;
diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c
index 57c3dc893..a286804f4 100644
--- a/src/ecdh_crypto.c
+++ b/src/ecdh_crypto.c
@@ -191,6 +191,17 @@ static ssh_string ssh_ecdh_generate(ssh_session session)
SSH_STRING_FREE(client_pubkey);
return SSH_ERROR;
}
+
+ /* Free any previously allocated privkey */
+ if (session->next_crypto->ecdh_privkey != NULL) {
+#if 1 //#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ EC_KEY_free(session->next_crypto->ecdh_privkey);
+#else
+ EVP_PKEY_free(session->next_crypto->ecdh_privkey);
+#endif
+ session->next_crypto->ecdh_privkey = NULL;
+ }
+
session->next_crypto->ecdh_privkey = key;
session->next_crypto->ecdh_client_pubkey = client_pubkey;
diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c
index a52ca84dd..8eabfe181 100644
--- a/src/ecdh_gcrypt.c
+++ b/src/ecdh_gcrypt.c
@@ -101,6 +101,12 @@ int ssh_client_ecdh_init(ssh_session session)
goto out;
}
+ /* Free any previously allocated privkey */
+ if (session->next_crypto->ecdh_privkey != NULL) {
+ gcry_sexp_release(session->next_crypto->ecdh_privkey);
+ session->next_crypto->ecdh_privkey = NULL;
+ }
+
session->next_crypto->ecdh_privkey = key;
key = NULL;
session->next_crypto->ecdh_client_pubkey = client_pubkey;
diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c
index 1d9c8f366..d31bfcc7a 100644
--- a/src/ecdh_mbedcrypto.c
+++ b/src/ecdh_mbedcrypto.c
@@ -70,6 +70,12 @@ int ssh_client_ecdh_init(ssh_session session)
return SSH_ERROR;
}
+ /* Free any previously allocated privkey */
+ if (session->next_crypto->ecdh_privkey != NULL) {
+ mbedtls_ecp_keypair_free(session->next_crypto->ecdh_privkey);
+ SAFE_FREE(session->next_crypto->ecdh_privkey);
+ }
+
session->next_crypto->ecdh_privkey = malloc(sizeof(mbedtls_ecp_keypair));
if (session->next_crypto->ecdh_privkey == NULL) {
return SSH_ERROR;
--
cgit v1.2.3
|