Version in base suite: 2.74.3-1 Base version: libsoup2.4_2.74.3-1 Target version: libsoup2.4_2.74.3-1+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libs/libsoup2.4/libsoup2.4_2.74.3-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libs/libsoup2.4/libsoup2.4_2.74.3-1+deb12u1.dsc changelog | 12 +++ patches/CVE-2024-52530.patch | 143 +++++++++++++++++++++++++++++++++++++++++ patches/CVE-2024-52531-1.patch | 39 +++++++++++ patches/CVE-2024-52531-2.patch | 126 ++++++++++++++++++++++++++++++++++++ patches/CVE-2024-52532-1.patch | 30 ++++++++ patches/CVE-2024-52532-2.patch | 36 ++++++++++ patches/CVE-2024-52532-3.patch | 39 +++++++++++ patches/series | 6 + 8 files changed, 431 insertions(+) diff -Nru libsoup2.4-2.74.3/debian/changelog libsoup2.4-2.74.3/debian/changelog --- libsoup2.4-2.74.3/debian/changelog 2022-10-11 19:28:32.000000000 +0000 +++ libsoup2.4-2.74.3/debian/changelog 2024-12-11 02:52:05.000000000 +0000 @@ -1,3 +1,15 @@ +libsoup2.4 (2.74.3-1+deb12u1) bookworm; urgency=high + + * Backport upstream fixes for + - CVE-2024-52530: HTTP request smuggling with null bytes at the end of + header names (Closes: #1088812) + - CVE-2024-52531: buffer overflow in soup_header_parse_param_list_strict + (Closes: #1089240) + - CVE-2024-52532: infinite loop / potential DoS in reading certain + data from WebSocket clients (Closes: #1089238). + + -- Sean Whitton Wed, 11 Dec 2024 10:52:05 +0800 + libsoup2.4 (2.74.3-1) unstable; urgency=medium * New upstream release (LP: #1992504) diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52530.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52530.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52530.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52530.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,143 @@ +From: Patrick Griffis +Date: Mon, 8 Jul 2024 12:33:15 -0500 +Subject: 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. + +(cherry picked from commit 04df03bc092ac20607f3e150936624d4f536e68b) +--- + 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 eec28ad..e5d3c03 100644 +--- a/libsoup/soup-headers.c ++++ b/libsoup/soup-headers.c +@@ -50,13 +50,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 +@@ -68,14 +69,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 946f118..e7d5e64 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); + diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-1.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-1.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-1.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,39 @@ +From: Patrick Griffis +Date: Mon, 16 Sep 2024 13:56:09 -0500 +Subject: Define GLIB_VERSION_MAX_ALLOWED and GLIB_VERSION_MIN_REQUIRED + +(cherry picked from commit 3c54033634ae537b52582900a7ba432c52ae8174) +--- + meson.build | 3 +++ + tests/hsts-db-test.c | 3 ++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 130f813..459eccc 100644 +--- a/meson.build ++++ b/meson.build +@@ -125,6 +125,9 @@ endif + + cdata = configuration_data() + ++cdata.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_70') ++cdata.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_70') ++ + brotlidec_dep = dependency('libbrotlidec', required : get_option('brotli')) + if brotlidec_dep.found() + cdata.set('WITH_BROTLI', true) +diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c +index 9f007fa..121a4a1 100644 +--- a/tests/hsts-db-test.c ++++ b/tests/hsts-db-test.c +@@ -1,8 +1,9 @@ ++#include "test-utils.h" ++ + #include + #include + + #include +-#include "test-utils.h" + + #define DB_FILE "hsts-db.sqlite" + diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-2.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-2.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52531-2.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,126 @@ +From: Patrick Griffis +Date: Tue, 27 Aug 2024 13:53:26 -0500 +Subject: 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. + +(cherry picked from commit a35222dd0bfab2ac97c10e86b95f762456628283) +--- + 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 e5d3c03..2d287fc 100644 +--- a/libsoup/soup-headers.c ++++ b/libsoup/soup-headers.c +@@ -643,8 +643,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; +@@ -658,10 +659,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) +@@ -690,14 +692,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; + } +@@ -707,15 +702,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; + +@@ -730,19 +727,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); + +@@ -750,11 +747,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); diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-1.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-1.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-1.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,30 @@ +From: Ignacio Casal Quinteiro +Date: Wed, 11 Sep 2024 11:52:11 +0200 +Subject: 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 + +(cherry picked from commit 6adc0e3eb74c257ed4e2a23eb4b2774fdb0d67be) +--- + libsoup/soup-websocket-connection.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libsoup/soup-websocket-connection.c b/libsoup/soup-websocket-connection.c +index a4095e1..9d5f4f8 100644 +--- a/libsoup/soup-websocket-connection.c ++++ b/libsoup/soup-websocket-connection.c +@@ -1140,9 +1140,9 @@ soup_websocket_connection_read (SoupWebsocketConnection *self) + } + + pv->incoming->len = len + count; +- } while (count > 0); + +- process_incoming (self); ++ process_incoming (self); ++ } while (count > 0 && !pv->close_sent && !pv->io_closing); + + if (end) { + if (!pv->close_sent || !pv->close_received) { diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-2.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-2.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-2.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,36 @@ +From: Ignacio Casal Quinteiro +Date: Wed, 2 Oct 2024 11:17:19 +0200 +Subject: 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 + +(cherry picked from commit 29b96fab2512666d7241e46c98cc45b60b795c0c) +--- + 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 5e40cf3..30a1f36 100644 +--- a/tests/websocket-test.c ++++ b/tests/websocket-test.c +@@ -1331,8 +1331,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 */ +@@ -1345,6 +1346,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); diff -Nru libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-3.patch libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-3.patch --- libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/CVE-2024-52532-3.patch 2024-12-11 02:52:05.000000000 +0000 @@ -0,0 +1,39 @@ +From: Simon McVittie +Date: Wed, 13 Nov 2024 14:14:23 +0000 +Subject: 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 +(cherry picked from commit 4c9e75c6676a37b6485620c332e568e1a3f530ff) +--- + 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 30a1f36..93e9b14 100644 +--- a/tests/websocket-test.c ++++ b/tests/websocket-test.c +@@ -1300,8 +1300,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 */ +@@ -1314,6 +1315,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); diff -Nru libsoup2.4-2.74.3/debian/patches/series libsoup2.4-2.74.3/debian/patches/series --- libsoup2.4-2.74.3/debian/patches/series 2022-10-11 19:28:32.000000000 +0000 +++ libsoup2.4-2.74.3/debian/patches/series 2024-12-11 02:52:05.000000000 +0000 @@ -2,3 +2,9 @@ tests-Skip-tests-if-unable-to-start-Apache.patch Record-Apache-error-log-for-unit-tests-and-show-it-during.patch Mark-XMLRPC-tests-as-flaky.patch +CVE-2024-52530.patch +CVE-2024-52531-1.patch +CVE-2024-52531-2.patch +CVE-2024-52532-1.patch +CVE-2024-52532-2.patch +CVE-2024-52532-3.patch