File: CVE-2025-8277.patch

package info (click to toggle)
libssh 0.11.2-1%2Bdeb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,668 kB
  • sloc: ansic: 100,163; cpp: 421; sh: 186; makefile: 25; javascript: 20; python: 9
file content (153 lines) | stat: -rw-r--r-- 5,408 bytes parent folder | download
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