From 97c1ca5c809635d910547b53f96ba7528b2a9e6f Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Fri, 30 Jan 2026 14:31:01 -0600 Subject: [PATCH] Backport patch for CVE-2026-0719 Fix NTLM authentication test failures in FIPS mode Resolves: RHEL-139834 --- CVE-2026-0719.patch | 102 +++++++++++++++++++++++++++++++++++++ libsoup.spec | 10 +++- no-ntlm-in-fips-mode.patch | 97 +++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 CVE-2026-0719.patch create mode 100644 no-ntlm-in-fips-mode.patch diff --git a/CVE-2026-0719.patch b/CVE-2026-0719.patch new file mode 100644 index 0000000..fbc7008 --- /dev/null +++ b/CVE-2026-0719.patch @@ -0,0 +1,102 @@ +From 509a0471b4a5f901596e6c669dbbf5313f637a4c Mon Sep 17 00:00:00 2001 +From: Mike Gorse +Date: Thu, 8 Jan 2026 16:19:37 -0600 +Subject: [PATCH] soup-auth-ntlm: Reject excessively long passwords + +According to +https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/ntlm-user-authentication, +the practical limit for a NTLM password is 128 Unicode characters, so it +should be safe to reject passwords longer than 256 bytes. Previously, +md4sum could overflow and cause an out-of-bounds memory access if an +extremely long password was provided. Also update md4sum to use unsigned +variables for size-related calculations, as a precaution. + +This is CVE-2026-0719. + +Closes #477. +--- + libsoup/soup-auth-ntlm.c | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/libsoup/soup-auth-ntlm.c b/libsoup/soup-auth-ntlm.c +index a4465ada..64eedc64 100644 +--- a/libsoup/soup-auth-ntlm.c ++++ b/libsoup/soup-auth-ntlm.c +@@ -349,6 +349,14 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg, + return FALSE; + } + ++ if (priv->password_state == SOUP_NTLM_PASSWORD_PROVIDED && !priv->nt_hash[0]) { ++ /* This can happen if an excessively long password was ++ * provided, in which case we don't try to hash */ ++ conn->state = SOUP_NTLM_FAILED; ++ priv->password_state = SOUP_NTLM_PASSWORD_REJECTED; ++ return TRUE; ++ } ++ + if (!soup_ntlm_parse_challenge (auth_header + 5, &conn->nonce, + priv->domain ? NULL : &priv->domain, + &conn->ntlmv2_session, &conn->negotiate_target, +@@ -439,8 +447,10 @@ soup_auth_ntlm_authenticate (SoupAuth *auth, const char *username, + priv->username = g_strdup (username); + } + +- soup_ntlm_nt_hash (password, priv->nt_hash); +- soup_ntlm_lanmanager_hash (password, priv->lm_hash); ++ if (strlen (password) < 256) { ++ soup_ntlm_nt_hash (password, priv->nt_hash); ++ soup_ntlm_lanmanager_hash (password, priv->lm_hash); ++ } + + priv->password_state = SOUP_NTLM_PASSWORD_PROVIDED; + } +@@ -606,7 +616,7 @@ soup_auth_ntlm_class_init (SoupAuthNTLMClass *auth_ntlm_class) + } + + static void md4sum (const unsigned char *in, +- int nbytes, ++ size_t nbytes, + unsigned char digest[16]); + + typedef guint32 DES_KS[16][2]; /* Single-key DES key schedule */ +@@ -652,7 +662,7 @@ soup_ntlm_nt_hash (const char *password, guchar hash[21]) + { + unsigned char *buf, *p; + +- p = buf = g_malloc (strlen (password) * 2); ++ p = buf = g_malloc_n (strlen (password), 2); + + while (*password) { + *p++ = *password++; +@@ -1091,15 +1101,16 @@ calc_response (const guchar *key, const guchar *plaintext, guchar *results) + #define ROT(val, n) ( ((val) << (n)) | ((val) >> (32 - (n))) ) + + static void +-md4sum (const unsigned char *in, int nbytes, unsigned char digest[16]) ++md4sum (const unsigned char *in, size_t nbytes, unsigned char digest[16]) + { + unsigned char *M; + guint32 A, B, C, D, AA, BB, CC, DD, X[16]; +- int pbytes, nbits = nbytes * 8, i, j; ++ size_t pbytes, nbits = nbytes * 8; ++ int i, j; + + /* There is *always* padding of at least one bit. */ + pbytes = ((119 - (nbytes % 64)) % 64) + 1; +- M = alloca (nbytes + pbytes + 8); ++ M = g_malloc (nbytes + pbytes + 8); + memcpy (M, in, nbytes); + memset (M + nbytes, 0, pbytes + 8); + M[nbytes] = 0x80; +@@ -1199,6 +1210,8 @@ md4sum (const unsigned char *in, int nbytes, unsigned char digest[16]) + digest[13] = (D >> 8) & 0xFF; + digest[14] = (D >> 16) & 0xFF; + digest[15] = (D >> 24) & 0xFF; ++ ++ g_free (M); + } + + +-- +2.52.0 + diff --git a/libsoup.spec b/libsoup.spec index 5840ac7..64029a3 100644 --- a/libsoup.spec +++ b/libsoup.spec @@ -2,7 +2,7 @@ Name: libsoup Version: 2.62.3 -Release: 11%{?dist} +Release: 12%{?dist} Summary: Soup, an HTTP library implementation License: LGPLv2 @@ -47,6 +47,10 @@ Patch0022: server-test-timeouts.patch Patch0023: CVE-2025-4945-CVE-2025-11021.patch # https://gitlab.gnome.org/GNOME/libsoup/-/issues/472 Patch0024: CVE-2025-14523.patch +# Downstream patch, needed due to glib2 gnutls-hmac.patch +Patch0025: no-ntlm-in-fips-mode.patch +# https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/494 +Patch0026: CVE-2026-0719.patch BuildRequires: chrpath BuildRequires: glib2-devel >= %{glib2_version} @@ -121,6 +125,10 @@ chrpath --delete $RPM_BUILD_ROOT%{_libdir}/*.so %{_datadir}/vala/vapi/libsoup-2.4.vapi %changelog +* Fri Jan 30 2026 Michael Catanzaro - 2.62.3-12 +- Backport patch for CVE-2026-0719 +- Fix NTLM authentication test failures in FIPS mode + * Wed Jan 07 2026 Michael Catanzaro - 2.62.3-11 - Backport patch for CVE-2025-14523 diff --git a/no-ntlm-in-fips-mode.patch b/no-ntlm-in-fips-mode.patch new file mode 100644 index 0000000..469682a --- /dev/null +++ b/no-ntlm-in-fips-mode.patch @@ -0,0 +1,97 @@ +From 00424003b2209b667a3c5c5b5b8167d4e100e63e Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Thu, 29 Jan 2026 15:06:17 -0600 +Subject: [PATCH] Disable NTLM auth and tests in FIPS mode + +This is a downstream Fedora/RHEL-ecosystem patch. Upstream GHmac +supports MD5 unconditionally, but in Fedora/RHEL trying to use MD5 HMAC +will crash if FIPS mode is enabled due to the glib2 package's +gnutls-hmac.patch, which I have thus far failed to upstream. This isn't +great, but it looks like finding an upstream solution will be difficult, +so we'll just have to carry this patch for now. + +https://gitlab.gnome.org/GNOME/glib/merge_requests/897 +--- + libsoup/soup-auth-ntlm.c | 12 ++++++++++++ + tests/ntlm-test.c | 21 +++++++++++++++++++++ + 2 files changed, 33 insertions(+) + +diff --git a/libsoup/soup-auth-ntlm.c b/libsoup/soup-auth-ntlm.c +index 2d078461..a4465ada 100644 +--- a/libsoup/soup-auth-ntlm.c ++++ b/libsoup/soup-auth-ntlm.c +@@ -445,6 +445,17 @@ soup_auth_ntlm_authenticate (SoupAuth *auth, const char *username, + priv->password_state = SOUP_NTLM_PASSWORD_PROVIDED; + } + ++static gboolean ++soup_auth_ntlm_can_authenticate (SoupAuth *auth) ++{ ++ GHmac *hmac = g_hmac_new (G_CHECKSUM_MD5, (const unsigned char *)"abc123", sizeof ("abc123")); ++ if (hmac) { ++ g_hmac_unref (hmac); ++ return TRUE; ++ } ++ return FALSE; ++} ++ + static gboolean + soup_auth_ntlm_is_authenticated (SoupAuth *auth) + { +@@ -577,6 +588,7 @@ soup_auth_ntlm_class_init (SoupAuthNTLMClass *auth_ntlm_class) + + auth_class->get_protection_space = soup_auth_ntlm_get_protection_space; + auth_class->authenticate = soup_auth_ntlm_authenticate; ++ auth_class->can_authenticate = soup_auth_ntlm_can_authenticate; + auth_class->is_authenticated = soup_auth_ntlm_is_authenticated; + + connauth_class->create_connection_state = soup_auth_ntlm_create_connection_state; +diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c +index 0cc41a7b..2cdd4611 100644 +--- a/tests/ntlm-test.c ++++ b/tests/ntlm-test.c +@@ -505,6 +505,17 @@ static const NtlmTest ntlmssp_tests[] = { + { "/ntlm/ssp/basic", "alice", FALSE, BUILTIN } + }; + ++static gboolean ++can_do_ntlm_test (void) ++{ ++ GHmac *hmac = g_hmac_new (G_CHECKSUM_MD5, (const unsigned char *)"abc123", sizeof ("abc123")); ++ if (hmac) { ++ g_hmac_unref (hmac); ++ return TRUE; ++ } ++ return FALSE; ++} ++ + static void + do_ntlm_test (TestServer *ts, + gconstpointer data) +@@ -512,6 +523,11 @@ do_ntlm_test (TestServer *ts, + const NtlmTest *test = data; + gboolean use_builtin_ntlm = TRUE; + ++ if (!can_do_ntlm_test ()) { ++ g_test_skip ("NTLM authentication not available (likely due to FIPS mode)"); ++ return; ++ } ++ + switch (test->ntlm_type) { + case BUILTIN: + /* Built-in NTLM auth support. (We set SOUP_NTLM_AUTH_DEBUG to +@@ -587,6 +603,11 @@ do_retrying_test (TestServer *ts, + + g_test_bug ("693222"); + ++ if (!can_do_ntlm_test ()) { ++ g_test_skip ("NTLM authentication not available (likely due to FIPS mode)"); ++ return; ++ } ++ + g_setenv ("SOUP_NTLM_AUTH_DEBUG", "", TRUE); + + debug_printf (1, " /alice\n"); +-- +2.52.0 +