Sync from SUSE:ALP:Source:Standard:1.0 libsoup revision 1ad5a741cb63c6f5917e7bf9deeff5e7

This commit is contained in:
2025-01-06 10:58:32 +01:00
parent 7d4d330b3e
commit 2670338188
7 changed files with 417 additions and 0 deletions

145
04df03bc.patch Normal file
View File

@@ -0,0 +1,145 @@
From 04df03bc092ac20607f3e150936624d4f536e68b Mon Sep 17 00:00:00 2001
From: Patrick Griffis <pgriffis@igalia.com>
Date: Mon, 8 Jul 2024 12:33:15 -0500
Subject: [PATCH] headers: Strictly don't allow NUL bytes
In the past (2015) this was allowed for some problematic sites. However Chromium also does not allow NUL bytes in either header names or values these days. So this should no longer be a problem.
---
libsoup/soup-headers.c | 15 +++------
tests/header-parsing-test.c | 62 +++++++++++++++++--------------------
2 files changed, 32 insertions(+), 45 deletions(-)
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
index a0cf351ac..f30ee467a 100644
--- a/libsoup/soup-headers.c
+++ b/libsoup/soup-headers.c
@@ -51,13 +51,14 @@ soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
* ignorable trailing whitespace.
*/
+ /* No '\0's are allowed */
+ if (memchr (str, '\0', len))
+ return FALSE;
+
/* Skip over the Request-Line / Status-Line */
headers_start = memchr (str, '\n', len);
if (!headers_start)
return FALSE;
- /* No '\0's in the Request-Line / Status-Line */
- if (memchr (str, '\0', headers_start - str))
- return FALSE;
/* We work on a copy of the headers, which we can write '\0's
* into, so that we don't have to individually g_strndup and
@@ -69,14 +70,6 @@ soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
headers_copy[copy_len] = '\0';
value_end = headers_copy;
- /* There shouldn't be any '\0's in the headers already, but
- * this is the web we're talking about.
- */
- while ((p = memchr (headers_copy, '\0', copy_len))) {
- memmove (p, p + 1, copy_len - (p - headers_copy));
- copy_len--;
- }
-
while (*(value_end + 1)) {
name = value_end + 1;
name_end = strchr (name, ':');
diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c
index edf8eebb3..715c2c6f2 100644
--- a/tests/header-parsing-test.c
+++ b/tests/header-parsing-test.c
@@ -358,24 +358,6 @@ static struct RequestTest {
}
},
- { "NUL in header name", "760832",
- "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36,
- SOUP_STATUS_OK,
- "GET", "/", SOUP_HTTP_1_1,
- { { "Host", "example.com" },
- { NULL }
- }
- },
-
- { "NUL in header value", "760832",
- "GET / HTTP/1.1\r\nHost: example\x00" "com\r\n", 35,
- SOUP_STATUS_OK,
- "GET", "/", SOUP_HTTP_1_1,
- { { "Host", "examplecom" },
- { NULL }
- }
- },
-
/************************/
/*** INVALID REQUESTS ***/
/************************/
@@ -448,6 +430,21 @@ static struct RequestTest {
SOUP_STATUS_EXPECTATION_FAILED,
NULL, NULL, -1,
{ { NULL } }
+ },
+
+ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377
+ { "NUL in header name", NULL,
+ "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36,
+ SOUP_STATUS_BAD_REQUEST,
+ NULL, NULL, -1,
+ { { NULL } }
+ },
+
+ { "NUL in header value", NULL,
+ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
+ SOUP_STATUS_BAD_REQUEST,
+ NULL, NULL, -1,
+ { { NULL } }
}
};
static const int num_reqtests = G_N_ELEMENTS (reqtests);
@@ -620,22 +617,6 @@ static struct ResponseTest {
{ NULL } }
},
- { "NUL in header name", "760832",
- "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28,
- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK",
- { { "Foo", "bar" },
- { NULL }
- }
- },
-
- { "NUL in header value", "760832",
- "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK",
- { { "Foo", "bar" },
- { NULL }
- }
- },
-
/********************************/
/*** VALID CONTINUE RESPONSES ***/
/********************************/
@@ -768,6 +749,19 @@ static struct ResponseTest {
{ { NULL }
}
},
+
+ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377
+ { "NUL in header name", NULL,
+ "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28,
+ -1, 0, NULL,
+ { { NULL } }
+ },
+
+ { "NUL in header value", "760832",
+ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
+ -1, 0, NULL,
+ { { NULL } }
+ },
};
static const int num_resptests = G_N_ELEMENTS (resptests);
--
GitLab

38
29b96fab.patch Normal file
View File

@@ -0,0 +1,38 @@
From 29b96fab2512666d7241e46c98cc45b60b795c0c Mon Sep 17 00:00:00 2001
From: Ignacio Casal Quinteiro <qignacio@amazon.com>
Date: Wed, 2 Oct 2024 11:17:19 +0200
Subject: [PATCH] websocket-test: disconnect error copy after the test ends
Otherwise the server will have already sent a few more wrong
bytes and the client will continue getting errors to copy
but the error is already != NULL and it will assert
---
tests/websocket-test.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 06c443bb5..6a48c1f9b 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -1539,8 +1539,9 @@ test_receive_invalid_encode_length_64 (Test *test,
GError *error = NULL;
InvalidEncodeLengthTest context = { test, NULL };
guint i;
+ guint error_id;
- g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
+ error_id = g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
g_signal_connect (test->client, "message", G_CALLBACK (on_binary_message), &received);
/* We use 127(\x7f) as payload length with 65535 extended length */
@@ -1553,6 +1554,7 @@ test_receive_invalid_encode_length_64 (Test *test,
WAIT_UNTIL (error != NULL || received != NULL);
g_assert_error (error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR);
g_clear_error (&error);
+ g_signal_handler_disconnect (test->client, error_id);
g_assert_null (received);
g_thread_join (thread);
--
GitLab

42
4c9e75c6.patch Normal file
View File

@@ -0,0 +1,42 @@
From 4c9e75c6676a37b6485620c332e568e1a3f530ff Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@debian.org>
Date: Wed, 13 Nov 2024 14:14:23 +0000
Subject: [PATCH] websocket-test: Disconnect error signal in another place
This is the same change as commit 29b96fab "websocket-test: disconnect
error copy after the test ends", and is done for the same reason, but
replicating it into a different function.
Fixes: 6adc0e3e "websocket: process the frame as soon as we read data"
Resolves: https://gitlab.gnome.org/GNOME/libsoup/-/issues/399
Signed-off-by: Simon McVittie <smcv@debian.org>
---
tests/websocket-test.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 6a48c1f9..723f2857 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -1508,8 +1508,9 @@ test_receive_invalid_encode_length_16 (Test *test,
GError *error = NULL;
InvalidEncodeLengthTest context = { test, NULL };
guint i;
+ guint error_id;
- g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
+ error_id = g_signal_connect (test->client, "error", G_CALLBACK (on_error_copy), &error);
g_signal_connect (test->client, "message", G_CALLBACK (on_binary_message), &received);
/* We use 126(~) as payload length with 125 extended length */
@@ -1522,6 +1523,7 @@ test_receive_invalid_encode_length_16 (Test *test,
WAIT_UNTIL (error != NULL || received != NULL);
g_assert_error (error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR);
g_clear_error (&error);
+ g_signal_handler_disconnect (test->client, error_id);
g_assert_null (received);
g_thread_join (thread);
--
GitLab

32
6adc0e3e.patch Normal file
View File

@@ -0,0 +1,32 @@
From 6adc0e3eb74c257ed4e2a23eb4b2774fdb0d67be Mon Sep 17 00:00:00 2001
From: Ignacio Casal Quinteiro <qignacio@amazon.com>
Date: Wed, 11 Sep 2024 11:52:11 +0200
Subject: [PATCH] websocket: process the frame as soon as we read data
Otherwise we can enter in a read loop because we were not
validating the data until the all the data was read.
Fixes #391
---
libsoup/websocket/soup-websocket-connection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libsoup/websocket/soup-websocket-connection.c b/libsoup/websocket/soup-websocket-connection.c
index a1a730473..a14481340 100644
--- a/libsoup/websocket/soup-websocket-connection.c
+++ b/libsoup/websocket/soup-websocket-connection.c
@@ -1199,9 +1199,9 @@ soup_websocket_connection_read (SoupWebsocketConnection *self)
}
priv->incoming->len = len + count;
- } while (count > 0);
- process_incoming (self);
+ process_incoming (self);
+ } while (count > 0 && !priv->close_sent && !priv->io_closing);
if (end) {
if (!priv->close_sent || !priv->close_received) {
--
GitLab

129
a35222dd.patch Normal file
View File

@@ -0,0 +1,129 @@
From a35222dd0bfab2ac97c10e86b95f762456628283 Mon Sep 17 00:00:00 2001
From: Patrick Griffis <pgriffis@igalia.com>
Date: Tue, 27 Aug 2024 13:53:26 -0500
Subject: [PATCH] headers: Be more robust against invalid input when parsing
params
If you pass invalid input to a function such as soup_header_parse_param_list_strict()
it can cause an overflow if it decodes the input to UTF-8.
This should never happen with valid UTF-8 input which libsoup's client API
ensures, however it's server API does not currently.
---
libsoup/soup-headers.c | 46 ++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
index f30ee467..613e1905 100644
--- a/libsoup/soup-headers.c
+++ b/libsoup/soup-headers.c
@@ -646,8 +646,9 @@ soup_header_contains (const char *header, const char *token)
}
static void
-decode_quoted_string (char *quoted_string)
+decode_quoted_string_inplace (GString *quoted_gstring)
{
+ char *quoted_string = quoted_gstring->str;
char *src, *dst;
src = quoted_string + 1;
@@ -661,10 +662,11 @@ decode_quoted_string (char *quoted_string)
}
static gboolean
-decode_rfc5987 (char *encoded_string)
+decode_rfc5987_inplace (GString *encoded_gstring)
{
char *q, *decoded;
gboolean iso_8859_1 = FALSE;
+ const char *encoded_string = encoded_gstring->str;
q = strchr (encoded_string, '\'');
if (!q)
@@ -696,14 +698,7 @@ decode_rfc5987 (char *encoded_string)
decoded = utf8;
}
- /* If encoded_string was UTF-8, then each 3-character %-escape
- * will be converted to a single byte, and so decoded is
- * shorter than encoded_string. If encoded_string was
- * iso-8859-1, then each 3-character %-escape will be
- * converted into at most 2 bytes in UTF-8, and so it's still
- * shorter.
- */
- strcpy (encoded_string, decoded);
+ g_string_assign (encoded_gstring, decoded);
g_free (decoded);
return TRUE;
}
@@ -713,15 +708,17 @@ parse_param_list (const char *header, char delim, gboolean strict)
{
GHashTable *params;
GSList *list, *iter;
- char *item, *eq, *name_end, *value;
- gboolean override, duplicated;
params = g_hash_table_new_full (soup_str_case_hash,
soup_str_case_equal,
- g_free, NULL);
+ g_free, g_free);
list = parse_list (header, delim);
for (iter = list; iter; iter = iter->next) {
+ char *item, *eq, *name_end;
+ gboolean override, duplicated;
+ GString *parsed_value = NULL;
+
item = iter->data;
override = FALSE;
@@ -736,19 +733,19 @@ parse_param_list (const char *header, char delim, gboolean strict)
*name_end = '\0';
- value = (char *)skip_lws (eq + 1);
+ parsed_value = g_string_new ((char *)skip_lws (eq + 1));
if (name_end[-1] == '*' && name_end > item + 1) {
name_end[-1] = '\0';
- if (!decode_rfc5987 (value)) {
+ if (!decode_rfc5987_inplace (parsed_value)) {
+ g_string_free (parsed_value, TRUE);
g_free (item);
continue;
}
override = TRUE;
- } else if (*value == '"')
- decode_quoted_string (value);
- } else
- value = NULL;
+ } else if (parsed_value->str[0] == '"')
+ decode_quoted_string_inplace (parsed_value);
+ }
duplicated = g_hash_table_lookup_extended (params, item, NULL, NULL);
@@ -756,11 +753,16 @@ parse_param_list (const char *header, char delim, gboolean strict)
soup_header_free_param_list (params);
params = NULL;
g_slist_foreach (iter, (GFunc)g_free, NULL);
+ if (parsed_value)
+ g_string_free (parsed_value, TRUE);
break;
- } else if (override || !duplicated)
- g_hash_table_replace (params, item, value);
- else
+ } else if (override || !duplicated) {
+ g_hash_table_replace (params, item, parsed_value ? g_string_free (parsed_value, FALSE) : NULL);
+ } else {
+ if (parsed_value)
+ g_string_free (parsed_value, TRUE);
g_free (item);
+ }
}
g_slist_free (list);
--
GitLab

View File

@@ -1,3 +1,20 @@
-------------------------------------------------------------------
Mon Dec 9 23:52:43 UTC 2024 - Michael Gorse <mgorse@suse.com>
- Add 04df03bc.patch: strictly don't allow NUL bytes in headers
(boo#1233285 CVE-2024-52530 glgo#GNOME/libsoup#377).
- Add 6adc0e3e.patch: websocket: Process the frame as soon as we
read data (boo#1233287 CVE-2024-52532 glgo#GNOME/libsoup#391).
- Add 29b96fab.patch: websocket-test: disconnect error copy after
the test ends (glgo#GNOME/libsoup#391).
- Add a35222dd.patch: be more robust against invalid input when
parsing params (boo#1233292 CVE-2024-52531
glgo#GNOME/libsoup!407).
- Add 4c9e75c6.patch: fix an intermittent test failure
(glgo#GNOME/soup#399).
- Increase test timeout on s390x. The http2-body-stream test can be
slow and sometimes times out in our builds.
-------------------------------------------------------------------
Sat Apr 29 19:26:55 UTC 2023 - Bjørn Lie <bjorn.lie@gmail.com>

View File

@@ -26,6 +26,16 @@ Group: Development/Libraries/GNOME
URL: https://wiki.gnome.org/Projects/libsoup
Source0: https://download.gnome.org/sources/libsoup/3.4/%{name}-%{version}.tar.xz
Source99: baselibs.conf
# PATCH-FIX-UPSTREAM 04df03bc.patch boo#1233285 mgorse@suse.com -- strictly don't allow NUL bytes in headers.
Patch0: https://gitlab.gnome.org/GNOME/libsoup/-/commit/04df03bc.patch
# PATCH-FIX-UPSTREAM 6adc0e3e.patch boo#1233287 mgorse@suse.com -- process the frame as soon as we read data.
Patch1: https://gitlab.gnome.org/GNOME/libsoup/-/commit/6adc0e3e.patch
# PATCH-FIX-UPSTREAM 29b96fab.patch boo#1233287 mgorse@suse.com -- websocket-test: disconnect error copy after the test ends.
Patch2: https://gitlab.gnome.org/GNOME/libsoup/-/commit/29b96fab.patch
# PATCH-FIX-UPSTREAM a35222dd.patch boo#1233292 mgorse@suse.com -- be more robust against invalid input when parsing params.
Patch3: https://gitlab.gnome.org/GNOME/libsoup/-/commit/a35222dd.patch
# PATCH-FIX-UPSTREAM 4c9e75c6.patch boo#1233287 mgorse@suse.com -- fix an intermittent test failure.
Patch4: https://gitlab.gnome.org/GNOME/libsoup/-/commit/4c9e75c6.patch
BuildRequires: glib-networking
BuildRequires: meson >= 0.53
@@ -140,7 +150,11 @@ mv %{buildroot}%{_datadir}/doc/%{name}-%{api_version} %{buildroot}%{_docdir}
%check
# Run the regression tests using GnuTLS NORMAL priority
export G_TLS_GNUTLS_PRIORITY=NORMAL
%ifarch s390x
%meson_test -t 5
%else
%meson_test
%endif
%ldconfig_scriptlets 3_0-0