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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
Consists of these fixes upstream:
From 87db2659ec608a977a63eea529f17b9168388d73 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 5 Aug 2025 18:42:31 +0200
Subject: CVE-2025-8277: packet: Adjust packet filter to work when DH-GEX is
guessed wrongly
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
From 8e4d67aa9eda455bfad9ac610e54b7a548d0aa08 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 6 Aug 2025 11:10:38 +0200
Subject: CVE-2025-8277: ecdh: Free previously allocated pubkeys
From 1c763e29d138db87665e98983f468d2dd0f286c1 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 6 Aug 2025 15:32:56 +0200
Subject: CVE-2025-8277: mbedtls: Avoid leaking ecdh keys
--- libssh-0.11.2.orig/src/dh_crypto.c
+++ libssh-0.11.2/src/dh_crypto.c
@@ -407,6 +407,11 @@ int ssh_dh_init_common(struct ssh_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;
--- libssh-0.11.2.orig/src/dh_key.c
+++ libssh-0.11.2/src/dh_key.c
@@ -237,6 +237,11 @@ int ssh_dh_init_common(struct ssh_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;
--- libssh-0.11.2.orig/src/ecdh_crypto.c
+++ libssh-0.11.2/src/ecdh_crypto.c
@@ -191,6 +191,17 @@ static ssh_string ssh_ecdh_generate(ssh_
#endif /* OPENSSL_VERSION_NUMBER */
return NULL;
}
+
+ /* Free any previously allocated privkey */
+ if (session->next_crypto->ecdh_privkey != NULL) {
+#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;
return pubkey_string;
}
@@ -219,6 +230,7 @@ int ssh_client_ecdh_init(ssh_session ses
return SSH_ERROR;
}
+ ssh_string_free(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey;
/* register the packet callbacks */
--- libssh-0.11.2.orig/src/ecdh_gcrypt.c
+++ libssh-0.11.2/src/ecdh_gcrypt.c
@@ -101,8 +101,15 @@ int ssh_client_ecdh_init(ssh_session ses
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;
+
+ SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL;
--- libssh-0.11.2.orig/src/ecdh_mbedcrypto.c
+++ libssh-0.11.2/src/ecdh_mbedcrypto.c
@@ -70,6 +70,12 @@ int ssh_client_ecdh_init(ssh_session ses
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;
@@ -110,6 +116,7 @@ int ssh_client_ecdh_init(ssh_session ses
goto out;
}
+ SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL;
--- libssh-0.11.2.orig/src/packet.c
+++ libssh-0.11.2/src/packet.c
@@ -294,6 +294,7 @@ static enum ssh_packet_filter_result_e s
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
* - dh_handshake_state == DH_STATE_INIT
* or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange)
+ * or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
*
* Transitions:
@@ -313,6 +314,7 @@ static enum ssh_packet_filter_result_e s
if ((session->dh_handshake_state != DH_STATE_INIT) &&
(session->dh_handshake_state != DH_STATE_INIT_SENT) &&
+ (session->dh_handshake_state != DH_STATE_REQUEST_SENT) &&
(session->dh_handshake_state != DH_STATE_FINISHED))
{
rc = SSH_PACKET_DENIED;
--- libssh-0.11.2.orig/src/wrapper.c
+++ libssh-0.11.2/src/wrapper.c
@@ -181,7 +181,10 @@ void crypto_free(struct ssh_crypto_struc
#endif /* OPENSSL_VERSION_NUMBER */
#elif defined HAVE_GCRYPT_ECC
gcry_sexp_release(crypto->ecdh_privkey);
-#endif
+#elif defined HAVE_LIBMBEDCRYPTO
+ mbedtls_ecp_keypair_free(crypto->ecdh_privkey);
+ SAFE_FREE(crypto->ecdh_privkey);
+#endif /* HAVE_LIBGCRYPT */
crypto->ecdh_privkey = NULL;
}
#endif
|