summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-1467.patch
blob: a1a130ee3ae473f8933e7513d46081b9bcdbe906 (plain)
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
From b4f1dcb89a552fc03bfd0e65830b4f76fdc4a232 Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Tue, 21 Apr 2026 17:10:37 +0800
Subject: [PATCH] Fix CVE-2026-1467

CVE: CVE-2026-1467
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/6dfe506618d2d5856618e5c0f85bd93386dc8012]

The original backport patch targets libsoup3. This patch has been
adapted accordingly for libsoup2, refer the openSUSE patch, see [1]

[1] https://www.suse.com/security/cve/CVE-2026-1467.html

Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
 libsoup/soup-auth.c    |  2 +-
 libsoup/soup-message.c |  5 +++-
 libsoup/soup-uri.c     | 60 ++++++++++++++++++++++++++++++++++++++++++
 libsoup/soup-uri.h     |  2 ++
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/libsoup/soup-auth.c b/libsoup/soup-auth.c
index 1896aab..e205fe3 100644
--- a/libsoup/soup-auth.c
+++ b/libsoup/soup-auth.c
@@ -535,7 +535,7 @@ GSList *
 soup_auth_get_protection_space (SoupAuth *auth, SoupURI *source_uri)
 {
 	g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL);
-	g_return_val_if_fail (source_uri != NULL, NULL);
+	g_return_val_if_fail (soup_uri_is_valid (source_uri), NULL);
 
 	return SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri);
 }
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index da32b42..cc4f22b 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -1044,7 +1044,7 @@ soup_message_new (const char *method, const char *uri_string)
 	uri = soup_uri_new (uri_string);
 	if (!uri)
 		return NULL;
-	if (!uri->host) {
+	if (!soup_uri_is_valid (uri)) {
 		soup_uri_free (uri);
 		return NULL;
 	}
@@ -1066,6 +1066,8 @@ soup_message_new (const char *method, const char *uri_string)
 SoupMessage *
 soup_message_new_from_uri (const char *method, SoupURI *uri)
 {
+	g_return_val_if_fail (soup_uri_is_valid (uri), NULL);
+
 	return g_object_new (SOUP_TYPE_MESSAGE,
 			     SOUP_MESSAGE_METHOD, method,
 			     SOUP_MESSAGE_URI, uri,
@@ -1676,6 +1678,7 @@ soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
 	SoupMessagePrivate *priv;
 
 	g_return_if_fail (SOUP_IS_MESSAGE (msg));
+	g_return_if_fail (soup_uri_is_valid (uri));
 	priv = soup_message_get_instance_private (msg);
 
 	if (priv->uri)
diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c
index bdb7a17..d781ff1 100644
--- a/libsoup/soup-uri.c
+++ b/libsoup/soup-uri.c
@@ -1342,6 +1342,66 @@ 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[] = { '\t', '\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 (SoupURI *uri)
+{
+        if (!uri)
+                return FALSE;
+
+        if (!is_host_valid (soup_uri_get_host (uri)))
+                return FALSE;
+
+        /* FIXME: validate other URI components? */
+
+        return TRUE;
+}
+
+
 gboolean
 soup_uri_is_http (SoupURI *uri, char **aliases)
 {
diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h
index 8015e4f..64099c3 100644
--- a/libsoup/soup-uri.h
+++ b/libsoup/soup-uri.h
@@ -133,6 +133,8 @@ guint       soup_uri_host_hash             (gconstpointer key);
 SOUP_AVAILABLE_IN_2_28
 gboolean    soup_uri_host_equal            (gconstpointer v1,
 					    gconstpointer v2);
+SOUP_AVAILABLE_IN_2_68
+gboolean     soup_uri_is_valid             (SoupURI       *uri);
 
 #define   SOUP_URI_IS_VALID(uri)       ((uri) && (uri)->scheme && (uri)->path)
 #define   SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path)
-- 
2.34.1