diff --git a/SPECS/libsoup/CVE-2026-1467.patch b/SPECS/libsoup/CVE-2026-1467.patch new file mode 100644 index 00000000000..dbc91e388f3 --- /dev/null +++ b/SPECS/libsoup/CVE-2026-1467.patch @@ -0,0 +1,230 @@ +From 07b08db35347fedf99f93cb2884702b1c989c96b Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Tue, 3 Feb 2026 13:02:16 +0000 +Subject: [PATCH] uri-utils: validate host in soup_uri_is_valid and replace + SOUP_URI_IS_VALID macro; update message/auth call sites; add tests + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport from existing Build 1042199 of https://gitlab.gnome.org/GNOME/libsoup/-/commit/167ef0c6817658c1a089c75c462482209e207db4.patch +--- + libsoup/auth/soup-auth.c | 2 +- + libsoup/soup-message.c | 8 ++--- + libsoup/soup-uri-utils-private.h | 5 ++- + libsoup/soup-uri-utils.c | 61 ++++++++++++++++++++++++++++++++ + tests/uri-parsing-test.c | 46 ++++++++++++++++++++++++ + 5 files changed, 116 insertions(+), 6 deletions(-) + +diff --git a/libsoup/auth/soup-auth.c b/libsoup/auth/soup-auth.c +index d9bf4af..278baa1 100644 +--- a/libsoup/auth/soup-auth.c ++++ b/libsoup/auth/soup-auth.c +@@ -643,7 +643,7 @@ GSList * + soup_auth_get_protection_space (SoupAuth *auth, GUri *source_uri) + { + g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL); +- g_return_val_if_fail (SOUP_URI_IS_VALID (source_uri), NULL); ++ g_return_val_if_fail (soup_uri_is_valid (source_uri), NULL); + + GUri *source_uri_normalized = soup_uri_copy_with_normalized_flags (source_uri); + GSList *ret = SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri_normalized); +diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c +index 2f5b267..77f326a 100644 +--- a/libsoup/soup-message.c ++++ b/libsoup/soup-message.c +@@ -923,7 +923,7 @@ soup_message_new (const char *method, const char *uri_string) + uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS, NULL); + if (!uri) + return NULL; +- if (!g_uri_get_host (uri)) { ++ if (!soup_uri_is_valid (uri)) { + g_uri_unref (uri); + return NULL; + } +@@ -946,7 +946,7 @@ SoupMessage * + soup_message_new_from_uri (const char *method, GUri *uri) + { + g_return_val_if_fail (method != NULL, NULL); +- g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); ++ g_return_val_if_fail (soup_uri_is_valid (uri), NULL); + + return g_object_new (SOUP_TYPE_MESSAGE, + "method", method, +@@ -966,7 +966,7 @@ soup_message_new_from_uri (const char *method, GUri *uri) + SoupMessage * + soup_message_new_options_ping (GUri *base_uri) + { +- g_return_val_if_fail (SOUP_URI_IS_VALID (base_uri), NULL); ++ g_return_val_if_fail (soup_uri_is_valid (base_uri), NULL); + + return g_object_new (SOUP_TYPE_MESSAGE, + "method", SOUP_METHOD_OPTIONS, +@@ -2039,7 +2039,7 @@ soup_message_set_uri (SoupMessage *msg, GUri *uri) + GUri *normalized_uri; + + g_return_if_fail (SOUP_IS_MESSAGE (msg)); +- g_return_if_fail (SOUP_URI_IS_VALID (uri)); ++ g_return_if_fail (soup_uri_is_valid (uri)); + + priv = soup_message_get_instance_private (msg); + +diff --git a/libsoup/soup-uri-utils-private.h b/libsoup/soup-uri-utils-private.h +index 3dbdb85..18aa60f 100644 +--- a/libsoup/soup-uri-utils-private.h ++++ b/libsoup/soup-uri-utils-private.h +@@ -10,6 +10,9 @@ + + G_BEGIN_DECLS + ++gboolean soup_uri_is_valid (GUri *uri); ++ ++ + gboolean soup_uri_is_http (GUri *uri); + + gboolean soup_uri_is_https (GUri *uri); +@@ -28,6 +31,6 @@ GUri *soup_uri_copy_with_normalized_flags (GUri *uri); + + char *soup_uri_get_host_for_headers (GUri *uri); + +-#define SOUP_URI_IS_VALID(x) (x && g_uri_get_host(x) && g_uri_get_host(x)[0]) ++ + + G_END_DECLS +diff --git a/libsoup/soup-uri-utils.c b/libsoup/soup-uri-utils.c +index ce9b2a1..d1fe0bd 100644 +--- a/libsoup/soup-uri-utils.c ++++ b/libsoup/soup-uri-utils.c +@@ -244,6 +244,67 @@ soup_uri_host_equal (gconstpointer v1, gconstpointer v2) + return g_ascii_strcasecmp (one_host, two_host) == 0; + } + ++ ++static gboolean ++is_valid_character_for_host (char c) ++{ ++ static const char forbidden_chars[] = { ' ', '\n', '\r', ' ', '#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|' }; ++ int i; ++ ++ for (i = 0; i < G_N_ELEMENTS (forbidden_chars); ++i) { ++ if (c == forbidden_chars[i]) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++is_host_valid (const char* host) ++{ ++ int i; ++ gboolean is_valid; ++ char *ascii_host = NULL; ++ ++ if (!host || !host[0]) ++ return FALSE; ++ ++ if (g_hostname_is_non_ascii (host)) { ++ ascii_host = g_hostname_to_ascii (host); ++ if (!ascii_host) ++ return FALSE; ++ ++ host = ascii_host; ++ } ++ ++ if ((g_ascii_isdigit (host[0]) || strchr (host, ':')) && g_hostname_is_ip_address (host)) { ++ g_free (ascii_host); ++ return TRUE; ++ } ++ ++ is_valid = TRUE; ++ for (i = 0; host[i] && is_valid; i++) ++ is_valid = is_valid_character_for_host (host[i]); ++ ++ g_free (ascii_host); ++ ++ return is_valid; ++} ++ ++gboolean ++soup_uri_is_valid (GUri *uri) ++{ ++ if (!uri) ++ return FALSE; ++ ++ if (!is_host_valid (g_uri_get_host (uri))) ++ return FALSE; ++ ++ /* FIXME: validate other URI components? */ ++ ++ return TRUE; ++} ++ + gboolean + soup_uri_is_https (GUri *uri) + { +diff --git a/tests/uri-parsing-test.c b/tests/uri-parsing-test.c +index 4c16d7e..d949324 100644 +--- a/tests/uri-parsing-test.c ++++ b/tests/uri-parsing-test.c +@@ -114,6 +114,50 @@ do_copy_tests (void) + g_uri_unref (copy); + + g_uri_unref (uri); ++ ++static struct { ++ const char *scheme; ++ const char *host; ++ const char *as_string; ++ gboolean valid; ++} valid_tests[] = { ++ { "http", "example.com", "http://example.com/", TRUE }, ++ { "http", "localhost", "http://localhost/", TRUE }, ++ { "http", "127.0.0.1", "http://127.0.0.1/", TRUE }, ++ { "http", "::1", "http://[::1]/", TRUE }, ++ { "http", "::192.168.0.10", "http://[::192.168.0.10]/", TRUE }, ++ { "http", "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/", TRUE }, ++ { "http", "\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb5\x8b\xe8\xaf\x95", "http://\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb5\x8b\xe8\xaf\x95/", TRUE }, ++ { "http", "012x:4567:89AB:cdef:3210:7654:ba98:FeDc", "http://012x:4567:89AB:cdef:3210:7654:ba98:FeDc/", FALSE }, ++ { "http", " example.com", "http:// example.com/", FALSE }, ++ { "http", "example.com\n", "http://example.com\n/", FALSE }, ++ { "http", "\r\nexample.com", "http://\r\nexample.com/", FALSE }, ++ { "http", "example .com", "http://example .com/", FALSE }, ++ { "http", "example:com", "http://example:com/", FALSE }, ++ { "http", "exampl.com", "http://exampl.com/", FALSE }, ++ { "http", "exampl[e].com", "http://exampl[e].com/", FALSE }, ++ { "http", "exampl^e.com", "http://exampl^e.com/", FALSE }, ++ { "http", "examp|e.com", "http://examp|e.com/", FALSE }, ++}; ++ ++static void ++do_valid_tests (void) ++{ ++ int i; ++ ++ for (i = 0; i < G_N_ELEMENTS (valid_tests); ++i) { ++ GUri *uri; ++ char *uri_str; ++ ++ uri = g_uri_build (SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_ENCODED, valid_tests[i].scheme, NULL, valid_tests[i].host, -1, "", NULL, NULL); ++ uri_str = g_uri_to_string (uri); ++ ++ g_assert_cmpstr (uri_str, ==, valid_tests[i].as_string); ++ g_assert_true (soup_uri_is_valid (uri) == valid_tests[i].valid); ++ ++ g_free (uri_str); ++ g_uri_unref (uri); ++ } + } + + #define CONTENT_TYPE_DEFAULT "text/plain;charset=US-ASCII" +@@ -194,6 +238,8 @@ main (int argc, char **argv) + g_test_add_func ("/uri/copy", do_copy_tests); + g_test_add_func ("/data", do_data_uri_tests); + g_test_add_func ("/path_and_query", do_path_and_query_tests); ++ g_test_add_func ("/uri/valid", do_valid_tests); ++ + + ret = g_test_run (); + +-- +2.45.4 + diff --git a/SPECS/libsoup/libsoup.spec b/SPECS/libsoup/libsoup.spec index 7a4b61361fc..4db2b4bd43a 100644 --- a/SPECS/libsoup/libsoup.spec +++ b/SPECS/libsoup/libsoup.spec @@ -2,7 +2,7 @@ Summary: libsoup HTTP client/server library Name: libsoup Version: %{BaseVersion}.4 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv2 Vendor: Microsoft Corporation Distribution: Mariner @@ -36,6 +36,7 @@ Patch17: CVE-2025-4476.patch Patch18: CVE-2025-4948.patch Patch19: CVE-2025-4969.patch Patch20: CVE-2025-11021.patch +Patch21: CVE-2026-1467.patch BuildRequires: meson @@ -148,6 +149,9 @@ find %{buildroot} -type f -name "*.la" -delete -print %defattr(-,root,root) %changelog +* Wed Feb 04 2026 Azure Linux Security Servicing Account - 3.0.4-11 +- Patch for CVE-2026-1467 + * Wed Oct 29 2025 Azure Linux Security Servicing Account - 3.0.4-10 - Patch for CVE-2025-11021