summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Marko <peter.marko@siemens.com>2025-07-27 19:59:57 +0200
committerSteve Sakoman <steve@sakoman.com>2025-08-04 06:40:00 -0700
commit1e39b807b7bd53bf65d22c2baaf8747f55676c83 (patch)
treeec7574bcf3db5a72304dc01444cdc3d821b8a8e1
parenta7033065b6f2948fc856b4e31c2633f39b58d8fc (diff)
downloadpoky-1e39b807b7bd53bf65d22c2baaf8747f55676c83.tar.gz
gnutls: patch CVE-2025-6395
Pick relevant commit from 3.8.10 release MR [1]. [1] https://gitlab.com/gnutls/gnutls/-/merge_requests/1979 (From OE-Core rev: 3680d0e2021c609f624c2170b061e6696fd8254c) Signed-off-by: Peter Marko <peter.marko@siemens.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-support/gnutls/gnutls/CVE-2025-6395.patch299
-rw-r--r--meta/recipes-support/gnutls/gnutls_3.7.4.bb1
2 files changed, 300 insertions, 0 deletions
diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2025-6395.patch b/meta/recipes-support/gnutls/gnutls/CVE-2025-6395.patch
new file mode 100644
index 0000000000..9bc98ef6e4
--- /dev/null
+++ b/meta/recipes-support/gnutls/gnutls/CVE-2025-6395.patch
@@ -0,0 +1,299 @@
1From 23135619773e6ec087ff2abc65405bd4d5676bad Mon Sep 17 00:00:00 2001
2From: Daiki Ueno <ueno@gnu.org>
3Date: Mon, 7 Jul 2025 11:15:45 +0900
4Subject: [PATCH] handshake: clear HSK_PSK_SELECTED is when resetting
5 binders
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10When a TLS 1.3 handshake involves HRR and resumption or PSK, and the
11second Client Hello omits PSK, the server would result in a NULL
12pointer dereference as the PSK binder information is cleared while the
13HSK_PSK_SELECTED flag is still set. This makes sure that
14HSK_PSK_SELECTED flag is always cleared when the PSK binders are
15reset. This also makes it clear the HSK_PSK_SELECTED flag is valid
16only during a handshake; after that, whether PSK is used can be
17checked with gnutls_auth_client_get_type.
18
19Reported by Stefan Bühler.
20
21Signed-off-by: Daiki Ueno <ueno@gnu.org>
22
23CVE: CVE-2025-6395
24Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/23135619773e6ec087ff2abc65405bd4d5676bad]
25Signed-off-by: Peter Marko <peter.marko@siemens.com>
26---
27 NEWS | 4 +
28 lib/handshake.c | 25 +++-
29 lib/state.c | 4 +-
30 tests/Makefile.am | 2 +
31 tests/tls13/hello_retry_request_psk.c | 173 ++++++++++++++++++++++++++
32 5 files changed, 204 insertions(+), 4 deletions(-)
33 create mode 100644 tests/tls13/hello_retry_request_psk.c
34
35diff --git a/NEWS b/NEWS
36index 1334516c6..d800e83b0 100644
37--- a/NEWS
38+++ b/NEWS
39@@ -5,6 +5,10 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc.
40 Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
41 See the end for copying conditions.
42
43+** libgnutls: Fix NULL pointer dereference when 2nd Client Hello omits PSK
44+ Reported by Stefan Bühler. [GNUTLS-SA-2025-07-07-4, CVSS: medium]
45+ [CVE-2025-6395]
46+
47 ** libgnutls: Fix heap read buffer overrun in parsing X.509 SCTS timestamps
48 Spotted by oss-fuzz and reported by OpenAI Security Research Team,
49 and fix developed by Andrew Hamilton. [GNUTLS-SA-2025-07-07-1,
50diff --git a/lib/handshake.c b/lib/handshake.c
51index 722307be7..489d02194 100644
52--- a/lib/handshake.c
53+++ b/lib/handshake.c
54@@ -590,9 +590,28 @@ static int set_auth_types(gnutls_session_t session)
55 /* Under TLS1.3 this returns a KX which matches the negotiated
56 * groups from the key shares; if we are resuming then the KX seen
57 * here doesn't match the original session. */
58- if (!session->internals.resumed)
59- kx = gnutls_kx_get(session);
60- else
61+ if (!session->internals.resumed) {
62+ const gnutls_group_entry_st *group = get_group(session);
63+
64+ if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
65+ if (group) {
66+ kx = group->pk == GNUTLS_PK_DH ?
67+ GNUTLS_KX_DHE_PSK :
68+ GNUTLS_KX_ECDHE_PSK;
69+ } else {
70+ kx = GNUTLS_KX_PSK;
71+ }
72+ } else if (group) {
73+ /* Not necessarily be RSA, but just to
74+ * make _gnutls_map_kx_get_cred below
75+ * work.
76+ */
77+ kx = group->pk == GNUTLS_PK_DH ?
78+ GNUTLS_KX_DHE_RSA :
79+ GNUTLS_KX_ECDHE_RSA;
80+ } else
81+ kx = GNUTLS_KX_UNKNOWN;
82+ } else
83 kx = GNUTLS_KX_UNKNOWN;
84 } else {
85 /* TLS1.2 or earlier, kx is associated with ciphersuite */
86diff --git a/lib/state.c b/lib/state.c
87index ec514c0cd..10ec0eadb 100644
88--- a/lib/state.c
89+++ b/lib/state.c
90@@ -206,7 +206,8 @@ gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session)
91 const gnutls_group_entry_st *group = get_group(session);
92
93 if (ver->tls13_sem) {
94- if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
95+ if (gnutls_auth_client_get_type(session) ==
96+ GNUTLS_CRD_PSK) {
97 if (group) {
98 if (group->pk == GNUTLS_PK_DH)
99 return GNUTLS_KX_DHE_PSK;
100@@ -357,6 +358,7 @@ void reset_binders(gnutls_session_t session)
101 _gnutls_free_temp_key_datum(&session->key.binders[0].psk);
102 _gnutls_free_temp_key_datum(&session->key.binders[1].psk);
103 memset(session->key.binders, 0, sizeof(session->key.binders));
104+ session->internals.hsk_flags &= ~HSK_PSK_SELECTED;
105 }
106
107 /* Check whether certificate credentials of type @cert_type are set
108diff --git a/tests/Makefile.am b/tests/Makefile.am
109index c2d226a00..e43faf10f 100644
110--- a/tests/Makefile.am
111+++ b/tests/Makefile.am
112@@ -128,6 +128,8 @@ ctests += tls13/hello_retry_request
113
114 ctests += tls13/hello_retry_request_resume
115
116+ctests += tls13/hello_retry_request_psk
117+
118 ctests += tls13/psk-ext
119
120 ctests += tls13/key_update
121diff --git a/tests/tls13/hello_retry_request_psk.c b/tests/tls13/hello_retry_request_psk.c
122new file mode 100644
123index 000000000..a20cb0d96
124--- /dev/null
125+++ b/tests/tls13/hello_retry_request_psk.c
126@@ -0,0 +1,173 @@
127+/*
128+ * Copyright (C) 2017-2025 Red Hat, Inc.
129+ *
130+ * Author: Nikos Mavrogiannopoulos, Daiki Ueno
131+ *
132+ * This file is part of GnuTLS.
133+ *
134+ * GnuTLS is free software; you can redistribute it and/or modify it
135+ * under the terms of the GNU General Public License as published by
136+ * the Free Software Foundation; either version 3 of the License, or
137+ * (at your option) any later version.
138+ *
139+ * GnuTLS is distributed in the hope that it will be useful, but
140+ * WITHOUT ANY WARRANTY; without even the implied warranty of
141+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
142+ * General Public License for more details.
143+ *
144+ * You should have received a copy of the GNU Lesser General Public License
145+ * along with this program. If not, see <https://www.gnu.org/licenses/>
146+ */
147+
148+#ifdef HAVE_CONFIG_H
149+#include "config.h"
150+#endif
151+
152+#include <stdio.h>
153+#include <stdlib.h>
154+#include <stdint.h>
155+
156+#include <string.h>
157+#include <gnutls/gnutls.h>
158+#include <assert.h>
159+
160+#include "cert-common.h"
161+#include "utils.h"
162+#include "tls13/ext-parse.h"
163+#include "eagain-common.h"
164+
165+/* This program exercises the case where a TLS 1.3 handshake ends up
166+ * with HRR, and the first CH includes PSK while the 2nd CH omits
167+ * it */
168+
169+const char *testname = "hello entry request";
170+
171+const char *side = "";
172+
173+#define myfail(fmt, ...) fail("%s: " fmt, testname, ##__VA_ARGS__)
174+
175+static void tls_log_func(int level, const char *str)
176+{
177+ fprintf(stderr, "%s|<%d>| %s", side, level, str);
178+}
179+
180+struct ctx_st {
181+ unsigned hrr_seen;
182+ unsigned hello_counter;
183+};
184+
185+static int pskfunc(gnutls_session_t session, const char *username,
186+ gnutls_datum_t *key)
187+{
188+ if (debug)
189+ printf("psk: username %s\n", username);
190+ key->data = gnutls_malloc(4);
191+ key->data[0] = 0xDE;
192+ key->data[1] = 0xAD;
193+ key->data[2] = 0xBE;
194+ key->data[3] = 0xEF;
195+ key->size = 4;
196+ return 0;
197+}
198+
199+static int hello_callback(gnutls_session_t session, unsigned int htype,
200+ unsigned post, unsigned int incoming,
201+ const gnutls_datum_t *msg)
202+{
203+ struct ctx_st *ctx = gnutls_session_get_ptr(session);
204+ assert(ctx != NULL);
205+
206+ if (htype == GNUTLS_HANDSHAKE_HELLO_RETRY_REQUEST)
207+ ctx->hrr_seen = 1;
208+
209+ if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO) {
210+ if (post == GNUTLS_HOOK_POST)
211+ ctx->hello_counter++;
212+ else {
213+ /* Unset the PSK credential to omit the extension */
214+ gnutls_credentials_set(session, GNUTLS_CRD_PSK, NULL);
215+ }
216+ }
217+
218+ return 0;
219+}
220+
221+void doit(void)
222+{
223+ int sret, cret;
224+ gnutls_psk_server_credentials_t scred;
225+ gnutls_psk_client_credentials_t ccred;
226+ gnutls_certificate_credentials_t ccred2;
227+ gnutls_session_t server, client;
228+ /* Need to enable anonymous KX specifically. */
229+ const gnutls_datum_t key = { (void *)"DEADBEEF", 8 };
230+
231+ struct ctx_st ctx;
232+ memset(&ctx, 0, sizeof(ctx));
233+
234+ global_init();
235+
236+ gnutls_global_set_log_function(tls_log_func);
237+ if (debug)
238+ gnutls_global_set_log_level(9);
239+
240+ /* Init server */
241+ assert(gnutls_psk_allocate_server_credentials(&scred) >= 0);
242+ gnutls_psk_set_server_credentials_function(scred, pskfunc);
243+
244+ gnutls_init(&server, GNUTLS_SERVER);
245+
246+ assert(gnutls_priority_set_direct(
247+ server,
248+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+DHE-PSK",
249+ NULL) >= 0);
250+
251+ gnutls_credentials_set(server, GNUTLS_CRD_PSK, scred);
252+ gnutls_transport_set_push_function(server, server_push);
253+ gnutls_transport_set_pull_function(server, server_pull);
254+ gnutls_transport_set_ptr(server, server);
255+
256+ /* Init client */
257+ assert(gnutls_psk_allocate_client_credentials(&ccred) >= 0);
258+ gnutls_psk_set_client_credentials(ccred, "test", &key,
259+ GNUTLS_PSK_KEY_HEX);
260+ assert(gnutls_certificate_allocate_credentials(&ccred2) >= 0);
261+
262+ assert(gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_KEY_SHARE_TOP) >= 0);
263+
264+ gnutls_session_set_ptr(client, &ctx);
265+
266+ cret = gnutls_priority_set_direct(
267+ client,
268+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519:+DHE-PSK",
269+ NULL);
270+ if (cret < 0)
271+ myfail("cannot set TLS 1.3 priorities\n");
272+
273+ gnutls_credentials_set(client, GNUTLS_CRD_PSK, ccred);
274+ gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred2);
275+ gnutls_transport_set_push_function(client, client_push);
276+ gnutls_transport_set_pull_function(client, client_pull);
277+ gnutls_transport_set_ptr(client, client);
278+
279+ gnutls_handshake_set_hook_function(client, GNUTLS_HANDSHAKE_ANY,
280+ GNUTLS_HOOK_BOTH, hello_callback);
281+
282+ HANDSHAKE_EXPECT(client, server, GNUTLS_E_AGAIN,
283+ GNUTLS_E_INSUFFICIENT_CREDENTIALS);
284+
285+ assert(ctx.hrr_seen != 0);
286+
287+ gnutls_bye(client, GNUTLS_SHUT_WR);
288+ gnutls_bye(server, GNUTLS_SHUT_WR);
289+
290+ gnutls_deinit(client);
291+ gnutls_deinit(server);
292+
293+ gnutls_psk_free_server_credentials(scred);
294+ gnutls_psk_free_client_credentials(ccred);
295+ gnutls_certificate_free_credentials(ccred2);
296+
297+ gnutls_global_deinit();
298+ reset_buffers();
299+}
diff --git a/meta/recipes-support/gnutls/gnutls_3.7.4.bb b/meta/recipes-support/gnutls/gnutls_3.7.4.bb
index 30d4342d00..8c8e08855b 100644
--- a/meta/recipes-support/gnutls/gnutls_3.7.4.bb
+++ b/meta/recipes-support/gnutls/gnutls_3.7.4.bb
@@ -37,6 +37,7 @@ SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar
37 file://3e94dcdff862ef5d6db8b5cc8e59310b5f0cdfe2 \ 37 file://3e94dcdff862ef5d6db8b5cc8e59310b5f0cdfe2 \
38 file://CVE-2025-32988.patch \ 38 file://CVE-2025-32988.patch \
39 file://CVE-2025-32990.patch \ 39 file://CVE-2025-32990.patch \
40 file://CVE-2025-6395.patch \
40 " 41 "
41 42
42SRC_URI[sha256sum] = "e6adbebcfbc95867de01060d93c789938cf89cc1d1f6ef9ef661890f6217451f" 43SRC_URI[sha256sum] = "e6adbebcfbc95867de01060d93c789938cf89cc1d1f6ef9ef661890f6217451f"