Version in base suite: 0.10.6-0+deb12u1 Base version: libssh_0.10.6-0+deb12u1 Target version: libssh_0.10.6-0+deb12u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libs/libssh/libssh_0.10.6-0+deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libs/libssh/libssh_0.10.6-0+deb12u2.dsc changelog | 20 + patches/0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch | 54 +++ patches/0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch | 29 + patches/0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch | 30 ++ patches/0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch | 37 ++ patches/0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch | 33 ++ patches/0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch | 148 ++++++++++ patches/CVE-2025-8114.patch | 32 ++ patches/CVE-2025-8277-1.patch | 36 ++ patches/CVE-2025-8277-2.patch | 108 +++++++ patches/CVE-2025-8277-3.patch | 44 ++ patches/CVE-2025-8277-4.patch | 44 ++ patches/series | 11 13 files changed, 626 insertions(+) diff -Nru libssh-0.10.6/debian/changelog libssh-0.10.6/debian/changelog --- libssh-0.10.6/debian/changelog 2023-12-25 10:15:40.000000000 +0000 +++ libssh-0.10.6/debian/changelog 2025-11-26 09:29:30.000000000 +0000 @@ -1,3 +1,23 @@ +libssh (0.10.6-0+deb12u2) bookworm; urgency=medium + + [ Martin Pitt ] + * stable-security → bookworm-security + * Backport security patches from 0.11.2. + - CVE-2025-4877: Write beyond bounds in binary to base64 conversion functions + - CVE-2025-4878: Use of uninitialized variable in privatekey_from_file() + - CVE-2025-5318: Likely read beyond bounds in sftp server handle management + - CVE-2025-5351: Double free in functions exporting keys + - CVE-2025-5372: ssh_kdf() returns a success code on certain failures + - CVE-2025-5987: Invalid return code for chacha20 poly1305 with OpenSSL backend + https://www.libssh.org/2025/06/24/libssh-0-11-2-security-and-bugfix-release/ + (Closes: #1108407) + + [ Emilio Pozuelo Monfort ] + * Add patch for CVE-2025-8114 + * Add patches for CVE-2025-8277 + + -- Emilio Pozuelo Monfort Wed, 26 Nov 2025 10:29:30 +0100 + libssh (0.10.6-0+deb12u1) bookworm-security; urgency=medium * New upstream security release: diff -Nru libssh-0.10.6/debian/patches/0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch libssh-0.10.6/debian/patches/0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch --- libssh-0.10.6/debian/patches/0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,54 @@ +From 1f2119c3ef2ee83d663a8eaec2887b4a7724a4a7 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 15 Apr 2025 11:41:24 +0200 +Subject: [PATCH 3/8] CVE-2025-4877 base64: Prevent integer overflow and + potential OOB + +Set maximum input to 256MB to have safe margin to the 1GB trigger point +for 32b arch. + +The OOB should not be reachable by any internal code paths as most of +the buffers and strings we use as input for this operation already have +similar limit and none really allows this much of data. + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider +(cherry picked from commit 00f09acbec55962839fc7837ef14c56fb8fbaf72) +--- + src/base64.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/base64.c b/src/base64.c +index 4148f49c..f42e0e80 100644 +--- a/src/base64.c ++++ b/src/base64.c +@@ -29,6 +29,9 @@ + #include "libssh/priv.h" + #include "libssh/buffer.h" + ++/* Do not allow encoding more than 256MB of data */ ++#define BASE64_MAX_INPUT_LEN 256 * 1024 * 1024 ++ + static + const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" +@@ -274,7 +277,15 @@ uint8_t *bin_to_base64(const uint8_t *source, size_t len) + { + uint8_t *base64 = NULL; + uint8_t *ptr = NULL; +- size_t flen = len + (3 - (len % 3)); /* round to upper 3 multiple */ ++ size_t flen = 0; ++ ++ /* Set the artificial upper limit for the input. Otherwise on 32b arch, the ++ * following line could overflow for sizes larger than SIZE_MAX / 4 */ ++ if (len > BASE64_MAX_INPUT_LEN) { ++ return NULL; ++ } ++ ++ flen = len + (3 - (len % 3)); /* round to upper 3 multiple */ + flen = (4 * flen) / 3 + 1; + + base64 = malloc(flen); +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch libssh-0.10.6/debian/patches/0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch --- libssh-0.10.6/debian/patches/0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,29 @@ +From dab8d2b63397046c4d1f5aa3f18a7c0f162a3311 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 22 Apr 2025 21:18:44 +0200 +Subject: [PATCH 4/8] CVE-2025-5318: sftpserver: Fix possible buffer overrun + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider + +(cherry-picked from commit 5f4ffda88770f95482f) +--- + src/sftpserver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sftpserver.c b/src/sftpserver.c +index 9117f155..b3349e16 100644 +--- a/src/sftpserver.c ++++ b/src/sftpserver.c +@@ -538,7 +538,7 @@ void *sftp_handle(sftp_session sftp, ssh_string handle){ + + memcpy(&val, ssh_string_data(handle), sizeof(uint32_t)); + +- if (val > SFTP_HANDLES) { ++ if (val >= SFTP_HANDLES) { + return NULL; + } + +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch libssh-0.10.6/debian/patches/0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch --- libssh-0.10.6/debian/patches/0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,30 @@ +From efa3d8ce232a21531a402c341e8ecdb0c943dbee Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 28 Apr 2025 11:04:55 +0200 +Subject: [PATCH 5/8] CVE-2025-4878 legacy: Properly check return value to + avoid NULL pointer dereference + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider + +(cherry-picked from commit b35ee876adc92a208) +--- + src/legacy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/legacy.c b/src/legacy.c +index 7b165dbe..c853cb38 100644 +--- a/src/legacy.c ++++ b/src/legacy.c +@@ -451,7 +451,7 @@ ssh_private_key privatekey_from_file(ssh_session session, + auth_fn, + auth_data, + &key); +- if (rc == SSH_ERROR) { ++ if (rc != SSH_OK) { + return NULL; + } + +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch libssh-0.10.6/debian/patches/0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch --- libssh-0.10.6/debian/patches/0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,37 @@ +From 2f7a6898497a23deae301f34611e8a6e24efa07a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 6 May 2025 22:43:31 +0200 +Subject: [PATCH 6/8] CVE-2025-5351 pki_crypto: Avoid double-free on low-memory + conditions + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider + +(cherry-picked from commit 6ddb730a273389838) +--- + src/pki_crypto.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/pki_crypto.c b/src/pki_crypto.c +index 5b0d7ded..aec49544 100644 +--- a/src/pki_crypto.c ++++ b/src/pki_crypto.c +@@ -2023,6 +2023,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + bignum_safe_free(bn); + bignum_safe_free(be); + OSSL_PARAM_free(params); ++ params = NULL; + #endif /* OPENSSL_VERSION_NUMBER */ + break; + } +@@ -2143,6 +2144,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + */ + #if 0 + OSSL_PARAM_free(params); ++ params = NULL; + #endif /* OPENSSL_VERSION_NUMBER */ + + if (key->type == SSH_KEYTYPE_SK_ECDSA && +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch libssh-0.10.6/debian/patches/0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch --- libssh-0.10.6/debian/patches/0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,33 @@ +From f41bc133e824faf0fa8b71a1e74e4c9cbe8b543a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 6 May 2025 22:51:41 +0200 +Subject: [PATCH 7/8] CVE-2025-5987 libcrypto: Correctly detect failures of + chacha initialization + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider + +(cherry-picked from commit 90b4845e0c98574bb) +--- + src/libcrypto.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libcrypto.c b/src/libcrypto.c +index 4f945d90..911b3630 100644 +--- a/src/libcrypto.c ++++ b/src/libcrypto.c +@@ -777,9 +777,9 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher, + SSH_LOG(SSH_LOG_WARNING, "EVP_CIPHER_CTX_new failed"); + goto out; + } +- ret = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL, ++ rv = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL, + u8key + CHACHA20_KEYLEN, NULL); +- if (ret != 1) { ++ if (rv != 1) { + SSH_LOG(SSH_LOG_WARNING, "EVP_CipherInit failed"); + goto out; + } +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch libssh-0.10.6/debian/patches/0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch --- libssh-0.10.6/debian/patches/0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,148 @@ +From 1808f0e65e2f672046470db2c1e682999360f92c Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 14 May 2025 14:07:58 +0200 +Subject: [PATCH 8/8] CVE-2025-5372 libgcrypto: Simplify error checking and + handling of return codes in ssh_kdf() + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider + +(cherry-picked from commit a9d8a3d44829cf9182b) +--- + src/libcrypto.c | 62 ++++++++++++++++++++++--------------------------- + 1 file changed, 28 insertions(+), 34 deletions(-) + +diff --git a/src/libcrypto.c b/src/libcrypto.c +index 911b3630..69a850de 100644 +--- a/src/libcrypto.c ++++ b/src/libcrypto.c +@@ -163,7 +163,7 @@ int ssh_kdf(struct ssh_crypto_struct *crypto, + uint8_t key_type, unsigned char *output, + size_t requested_len) + { +- int rc = -1; ++ int ret = SSH_ERROR, rv; + #if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); + #else +@@ -185,81 +185,75 @@ int ssh_kdf(struct ssh_crypto_struct *crypto, + } + + #if OPENSSL_VERSION_NUMBER < 0x30000000L +- rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, ++ rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, + sshkdf_digest_to_md(crypto->digest_type)); +- if (rc != 1) { ++ if (rv != 1) { + goto out; + } +- rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key, key_len); +- if (rc != 1) { ++ rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key, key_len); ++ if (rv != 1) { + goto out; + } +- rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, ++ rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, + crypto->secret_hash, crypto->digest_len); +- if (rc != 1) { ++ if (rv != 1) { + goto out; + } +- rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, key_type); +- if (rc != 1) { ++ rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, key_type); ++ if (rv != 1) { + goto out; + } +- rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, ++ rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, + crypto->session_id, crypto->session_id_len); +- if (rc != 1) { ++ if (rv != 1) { + goto out; + } +- rc = EVP_KDF_derive(ctx, output, requested_len); +- if (rc != 1) { ++ rv = EVP_KDF_derive(ctx, output, requested_len); ++ if (rv != 1) { + goto out; + } + #else +- rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST, ++ rv = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST, + md, strlen(md)); +- if (rc != 1) { +- rc = -1; ++ if (rv != 1) { + goto out; + } +- rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY, ++ rv = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY, + key, key_len); +- if (rc != 1) { +- rc = -1; ++ if (rv != 1) { + goto out; + } +- rc = OSSL_PARAM_BLD_push_octet_string(param_bld, ++ rv = OSSL_PARAM_BLD_push_octet_string(param_bld, + OSSL_KDF_PARAM_SSHKDF_XCGHASH, + crypto->secret_hash, + crypto->digest_len); +- if (rc != 1) { +- rc = -1; ++ if (rv != 1) { + goto out; + } +- rc = OSSL_PARAM_BLD_push_octet_string(param_bld, ++ rv = OSSL_PARAM_BLD_push_octet_string(param_bld, + OSSL_KDF_PARAM_SSHKDF_SESSION_ID, + crypto->session_id, + crypto->session_id_len); +- if (rc != 1) { +- rc = -1; ++ if (rv != 1) { + goto out; + } +- rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE, ++ rv = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE, + (const char*)&key_type, 1); +- if (rc != 1) { +- rc = -1; ++ if (rv != 1) { + goto out; + } + + params = OSSL_PARAM_BLD_to_param(param_bld); + if (params == NULL) { +- rc = -1; + goto out; + } + +- rc = EVP_KDF_derive(ctx, output, requested_len, params); +- if (rc != 1) { +- rc = -1; ++ rv = EVP_KDF_derive(ctx, output, requested_len, params); ++ if (rv != 1) { + goto out; + } + #endif /* OPENSSL_VERSION_NUMBER */ ++ ret = SSH_OK; + + out: + #if OPENSSL_VERSION_NUMBER >= 0x30000000L +@@ -267,8 +261,8 @@ out: + OSSL_PARAM_free(params); + #endif + EVP_KDF_CTX_free(ctx); +- if (rc < 0) { +- return rc; ++ if (ret < 0) { ++ return ret; + } + return 0; + } +-- +2.50.0 + diff -Nru libssh-0.10.6/debian/patches/CVE-2025-8114.patch libssh-0.10.6/debian/patches/CVE-2025-8114.patch --- libssh-0.10.6/debian/patches/CVE-2025-8114.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/CVE-2025-8114.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,32 @@ +From 65f363c9e3a22b90af7f74b5c439a133b1047379 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 6 Aug 2025 15:17:59 +0200 +Subject: CVE-2025-8114: Fix NULL pointer dereference after allocation failure + +--- libssh-0.11.2.orig/src/kex.c ++++ libssh-0.11.2/src/kex.c +@@ -1487,6 +1487,8 @@ int ssh_make_sessionid(ssh_session sessi + ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf)); + #endif + ++ /* Set rc for the following switch statement in case we goto error. */ ++ rc = SSH_ERROR; + switch (session->next_crypto->kex_type) { + case SSH_KEX_DH_GROUP1_SHA1: + case SSH_KEX_DH_GROUP14_SHA1: +@@ -1546,6 +1548,7 @@ int ssh_make_sessionid(ssh_session sessi + session->next_crypto->secret_hash); + break; + } ++ + /* During the first kex, secret hash and session ID are equal. However, after + * a key re-exchange, a new secret hash is calculated. This hash will not replace + * but complement existing session id. +@@ -1554,6 +1557,7 @@ int ssh_make_sessionid(ssh_session sessi + session->next_crypto->session_id = malloc(session->next_crypto->digest_len); + if (session->next_crypto->session_id == NULL) { + ssh_set_error_oom(session); ++ rc = SSH_ERROR; + goto error; + } + memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash, diff -Nru libssh-0.10.6/debian/patches/CVE-2025-8277-1.patch libssh-0.10.6/debian/patches/CVE-2025-8277-1.patch --- libssh-0.10.6/debian/patches/CVE-2025-8277-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/CVE-2025-8277-1.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,36 @@ +From 87db2659ec608a977a63eea529f17b9168388d73 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +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 + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider +(cherry picked from commit 4310a696f2d632c6742678077d703d9b9ff3bc0e) +--- + src/packet.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/packet.c b/src/packet.c +index f15aa2ad5..f54b3158d 100644 +--- a/src/packet.c ++++ b/src/packet.c +@@ -294,6 +294,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se + * 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 ssh_packet_incoming_filter(ssh_session se + + 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; +-- +cgit v1.2.3 + diff -Nru libssh-0.10.6/debian/patches/CVE-2025-8277-2.patch libssh-0.10.6/debian/patches/CVE-2025-8277-2.patch --- libssh-0.10.6/debian/patches/CVE-2025-8277-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/CVE-2025-8277-2.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,108 @@ +From 266174a6d36687b65cf90174f06af90b8b27c65f Mon Sep 17 00:00:00 2001 +From: Francesco Rollo +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 +Reviewed-by: Andreas Schneider +(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 + diff -Nru libssh-0.10.6/debian/patches/CVE-2025-8277-3.patch libssh-0.10.6/debian/patches/CVE-2025-8277-3.patch --- libssh-0.10.6/debian/patches/CVE-2025-8277-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/CVE-2025-8277-3.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,44 @@ +From 8e4d67aa9eda455bfad9ac610e54b7a548d0aa08 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 6 Aug 2025 11:10:38 +0200 +Subject: CVE-2025-8277: ecdh: Free previously allocated pubkeys + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider +(cherry picked from commit c9d95ab0c7a52b231bcec09afbea71944ed0d852) +--- + src/ecdh_crypto.c | 1 + + src/ecdh_gcrypt.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c +index a286804f4..fb707c321 100644 +--- a/src/ecdh_crypto.c ++++ b/src/ecdh_crypto.c +@@ -230,6 +230,7 @@ int ssh_client_ecdh_init(ssh_session session) + + + session->next_crypto->ecdh_privkey = key; ++ ssh_string_free(session->next_crypto->ecdh_client_pubkey); + session->next_crypto->ecdh_client_pubkey = client_pubkey; + + /* register the packet callbacks */ +diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c +index 8eabfe181..5dcd3929a 100644 +--- a/src/ecdh_gcrypt.c ++++ b/src/ecdh_gcrypt.c +@@ -106,9 +106,10 @@ int ssh_client_ecdh_init(ssh_session session) + 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; + +-- +cgit v1.2.3 + diff -Nru libssh-0.10.6/debian/patches/CVE-2025-8277-4.patch libssh-0.10.6/debian/patches/CVE-2025-8277-4.patch --- libssh-0.10.6/debian/patches/CVE-2025-8277-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ libssh-0.10.6/debian/patches/CVE-2025-8277-4.patch 2025-11-26 09:29:30.000000000 +0000 @@ -0,0 +1,44 @@ +From 1c763e29d138db87665e98983f468d2dd0f286c1 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 6 Aug 2025 15:32:56 +0200 +Subject: CVE-2025-8277: mbedtls: Avoid leaking ecdh keys + +Signed-off-by: Jakub Jelen +Reviewed-by: Andreas Schneider +(cherry picked from commit ffed80f8c078122990a4eba2b275facd56dd43e0) +--- + src/ecdh_mbedcrypto.c | 1 + + src/wrapper.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c +index d31bfcc7a..860543d61 100644 +--- a/src/ecdh_mbedcrypto.c ++++ b/src/ecdh_mbedcrypto.c +@@ -116,6 +116,7 @@ int ssh_client_ecdh_init(ssh_session session) + goto out; + } + ++ SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey); + session->next_crypto->ecdh_client_pubkey = client_pubkey; + client_pubkey = NULL; + +diff --git a/src/wrapper.c b/src/wrapper.c +index 8996b8ce6..625130166 100644 +--- a/src/wrapper.c ++++ b/src/wrapper.c +@@ -181,7 +181,10 @@ void crypto_free(struct ssh_crypto_struct *crypto) + #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 +-- +cgit v1.2.3 + diff -Nru libssh-0.10.6/debian/patches/series libssh-0.10.6/debian/patches/series --- libssh-0.10.6/debian/patches/series 2023-12-25 10:15:40.000000000 +0000 +++ libssh-0.10.6/debian/patches/series 2025-11-26 09:29:30.000000000 +0000 @@ -1,5 +1,16 @@ 0001-Fix-regression-in-IPv6-addresses-in-hostname-parsing.patch 0002-tests-Increase-test-coverage-for-IPv6-address-parsin.patch +0003-CVE-2025-4877-base64-Prevent-integer-overflow-and-po.patch +0004-CVE-2025-5318-sftpserver-Fix-possible-buffer-overrun.patch +0005-CVE-2025-4878-legacy-Properly-check-return-value-to-.patch +0006-CVE-2025-5351-pki_crypto-Avoid-double-free-on-low-me.patch +0007-CVE-2025-5987-libcrypto-Correctly-detect-failures-of.patch +0008-CVE-2025-5372-libgcrypto-Simplify-error-checking-and.patch 1003-custom-lib-names.patch 2003-disable-expand_tilde_unix-test.patch 2004-install-static-lib.patch +CVE-2025-8114.patch +CVE-2025-8277-1.patch +CVE-2025-8277-2.patch +CVE-2025-8277-3.patch +CVE-2025-8277-4.patch