diff --git a/backport-CVE-2024-52531.patch b/backport-CVE-2024-52531.patch deleted file mode 100644 index 8864fd2e39b9f1460e0ef89b586e0b04c7a9a7e9..0000000000000000000000000000000000000000 --- a/backport-CVE-2024-52531.patch +++ /dev/null @@ -1,285 +0,0 @@ -From b1d22b0cd1fe363ccce462d1a147b65283883b75 Mon Sep 17 00:00:00 2001 -From: renwang -Date: Thu, 12 Dec 2024 11:21:48 +0800 -Subject: [PATCH] change - ---- - fuzzing/fuzz.h | 8 ++++++- - fuzzing/fuzz_header_parsing.c | 19 +++++++++++++++ - fuzzing/fuzz_header_parsing.dict | 8 +++++++ - fuzzing/meson.build | 2 ++ - libsoup/soup-headers.c | 40 ++++++++++++++++++++------------ - meson.build | 3 +++ - tests/header-parsing-test.c | 12 +++++++++- - tests/hsts-db-test.c | 3 ++- - tests/proxy-test.c | 2 +- - 9 files changed, 78 insertions(+), 19 deletions(-) - create mode 100644 fuzzing/fuzz_header_parsing.c - create mode 100644 fuzzing/fuzz_header_parsing.dict - -diff --git a/fuzzing/fuzz.h b/fuzzing/fuzz.h -index 0d38028..8ec48f3 100644 ---- a/fuzzing/fuzz.h -+++ b/fuzzing/fuzz.h -@@ -1,6 +1,7 @@ - #include "libsoup/soup.h" - - int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); -+static int set_logger = 0; - - #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - static GLogWriterOutput -@@ -16,6 +17,11 @@ static void - fuzz_set_logging_func (void) - { - #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -- g_log_set_writer_func (empty_logging_func, NULL, NULL); -+ if(!set_logger) -+ { -+ set_logger = 1; -+ g_log_set_writer_func (empty_logging_func, NULL, NULL); -+ -+ } - #endif - } -diff --git a/fuzzing/fuzz_header_parsing.c b/fuzzing/fuzz_header_parsing.c -new file mode 100644 -index 0000000..a8e5c1f ---- /dev/null -+++ b/fuzzing/fuzz_header_parsing.c -@@ -0,0 +1,19 @@ -+#include "fuzz.h" -+ -+int -+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) -+{ -+ GHashTable *elements; -+ -+ // We only accept NUL terminated strings -+ if (!size || data[size - 1] != '\0') -+ return 0; -+ -+ fuzz_set_logging_func (); -+ -+ elements = soup_header_parse_param_list((char*)data); -+ -+ g_hash_table_unref(elements); -+ -+ return 0; -+} -\ No newline at end of file -diff --git a/fuzzing/fuzz_header_parsing.dict b/fuzzing/fuzz_header_parsing.dict -new file mode 100644 -index 0000000..1562ca3 ---- /dev/null -+++ b/fuzzing/fuzz_header_parsing.dict -@@ -0,0 +1,8 @@ -+"*=UTF-8''" -+"*=iso-8859-1''" -+"'" -+"''" -+"=" -+"*=" -+""" -+";" -\ No newline at end of file -diff --git a/fuzzing/meson.build b/fuzzing/meson.build -index b14cbb5..5dd0f41 100644 ---- a/fuzzing/meson.build -+++ b/fuzzing/meson.build -@@ -5,6 +5,7 @@ fuzz_targets = [ - 'fuzz_cookie_parse', - 'fuzz_content_sniffer', - 'fuzz_date_time', -+ 'fuzz_header_parsing', - ] - - fuzzing_args = '-fsanitize=fuzzer,address,undefined' -@@ -34,6 +35,7 @@ if have_fuzzing and (fuzzing_feature.enabled() or fuzzing_feature.auto()) - '-runs=200000', - '-artifact_prefix=meson-logs/' + target + '-', - '-print_final_stats=1', -+ '-max_len=4096', - ] + extra_args, - env: [ - 'ASAN_OPTIONS=fast_unwind_on_malloc=0', -diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c -index f30ee46..79320e3 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) -@@ -703,7 +705,7 @@ decode_rfc5987 (char *encoded_string) - * 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 +715,18 @@ 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 +741,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 +761,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 --git a/meson.build b/meson.build -index 73a9fa0..3a5d354 100644 ---- a/meson.build -+++ b/meson.build -@@ -112,6 +112,9 @@ glib_deps = [glib_dep, gmodule_dep, gobject_dep, gio_dep] - - cdata = configuration_data() - -+cdata.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_70') -+cdata.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_70') -+ - libnghttp2_dep = dependency('libnghttp2') - if (libnghttp2_dep.version() == 'unknown' and (libnghttp2_dep.type_name() == 'internal' or cc.has_function('nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation', prefix : '#include ', dependencies : libnghttp2_dep))) or libnghttp2_dep.version().version_compare('>=1.50') - cdata.set('HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION', '1') -diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c -index 715c2c6..9d85705 100644 ---- a/tests/header-parsing-test.c -+++ b/tests/header-parsing-test.c -@@ -818,13 +818,23 @@ static struct ParamListTest { - { "filename", "filename.jpg" }, - }, - }, -- - { FALSE, - "attachment; filename*=UTF-8''t%C3%A9st.txt; filename=\"test.txt\"", - { { "attachment", NULL }, - { "filename", "t\xC3\xA9st.txt" }, - }, - }, -+ -+ /* This tests invalid UTF-8 data which *should* never be passed here but it was designed to be robust against it. */ -+ { TRUE, -+ "invalid*=\x69\x27\x27\x93\x93\x93\x93\xff\x61\x61\x61\x61\x61\x61\x61\x62\x63\x64\x65\x0a; filename*=iso-8859-1''\x69\x27\x27\x93\x93\x93\x93\xff\x61\x61\x61\x61\x61\x61\x61\x62\x63\x64\x65\x0a; foo", -+ { -+ { "filename", "i''\302\223\302\223\302\223\302\223\303\277aaaaaaabcde" }, -+ { "invalid", "\302\223\302\223\302\223\302\223\303\277aaaaaaabcde" }, -+ { "foo", NULL }, -+ -+ }, -+ } - }; - static const int num_paramlisttests = G_N_ELEMENTS (paramlisttests); - -diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c -index 1149a04..04d7c4f 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" - #include "soup-uri-utils-private.h" - - #define DB_FILE "hsts-db.sqlite" -diff --git a/tests/proxy-test.c b/tests/proxy-test.c -index ec03936..1125dad 100644 ---- a/tests/proxy-test.c -+++ b/tests/proxy-test.c -@@ -1,8 +1,8 @@ - /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ - --#include - #include "test-utils.h" - -+#include - typedef struct { - const char *explanation; - const char *url; --- -2.20.1 - diff --git a/backport-CVE-2024-52532.patch b/backport-CVE-2024-52532.patch deleted file mode 100644 index a0b6f91248ba27f87c63521be7264c9fdc348b3f..0000000000000000000000000000000000000000 --- a/backport-CVE-2024-52532.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 6adc0e3eb74c257ed4e2a23eb4b2774fdb0d67be Mon Sep 17 00:00:00 2001 -From: Ignacio Casal Quinteiro -Date: Wed, 11 Sep 2024 11:52:11 +0200 -Subject: [PATCH 1/2] 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 - - -From 29b96fab2512666d7241e46c98cc45b60b795c0c Mon Sep 17 00:00:00 2001 -From: Ignacio Casal Quinteiro -Date: Wed, 2 Oct 2024 11:17:19 +0200 -Subject: [PATCH 2/2] 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 - diff --git a/libsoup-3.4.4.tar.xz b/libsoup-3.4.4.tar.xz deleted file mode 100644 index f08c2a15fb9eeed01510caaa8dca8d41c001f38c..0000000000000000000000000000000000000000 Binary files a/libsoup-3.4.4.tar.xz and /dev/null differ diff --git a/libsoup-3.4.5.tar.xz b/libsoup-3.4.5.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..edb5ad7f1ba66e3e3141a855d7a3c0e2dc540585 Binary files /dev/null and b/libsoup-3.4.5.tar.xz differ diff --git a/libsoup3.spec b/libsoup3.spec index c8449b165e039995e1d8a4e62d14866208042619..dea59dfec443e64fb59af59d964506586ad6420c 100644 --- a/libsoup3.spec +++ b/libsoup3.spec @@ -1,29 +1,35 @@ %global glib2_version 2.69.1 +%bcond_without sysprof + Name: libsoup3 -Version: 3.4.4 -Release: 5 +Version: 3.4.5 +Release: 1 Summary: Soup, an HTTP library implementation -License: LGPLv2 +License: LGPL-2.0-or-later URL: https://wiki.gnome.org/Projects/libsoup Source0: https://download.gnome.org/sources/libsoup/3.4/libsoup-%{version}.tar.xz -Patch0001: backport-CVE-2024-52532.patch Patch0002: backport-CVE-2024-52530.patch -Patch0003: backport-CVE-2024-52531.patch Patch0004: backport-CVE-2025-4476.patch -BuildRequires: gcc meson gettext vala krb5-devel samba-winbind-clients -BuildRequires: gi-docgen >= 2021.1 -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(gio-2.0) -BuildRequires: glib-networking -BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: gcc gettext vala krb5-devel samba-winbind-clients +BuildRequires: meson >= 0.54 +BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version} +BuildRequires: pkgconfig(gio-unix-2.0) >= %{glib2_version} +BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} +BuildRequires: pkgconfig(gmodule-2.0) >= %{glib2_version} +BuildRequires: pkgconfig(gobject-2.0) >= %{glib2_version} BuildRequires: pkgconfig(libbrotlidec) -BuildRequires: pkgconfig(libpsl) +BuildRequires: pkgconfig(libnghttp2) +BuildRequires: pkgconfig(libpsl) >= 0.20 BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(zlib) +BuildRequires: gi-docgen >= 2021.1 +BuildRequires: glib-networking +%if %{with sysprof} BuildRequires: pkgconfig(sysprof-capture-4) -BuildRequires: pkgconfig(libnghttp2) +%endif Recommends: glib-networking >= %{glib2_version} @@ -53,7 +59,7 @@ you to develop applications that use the libsoup library. %autosetup -p1 -n libsoup-%{version} %build -%meson -Ddocs=enabled -Dtests=false -Dautobahn=disabled -Dpkcs11_tests=disabled +%meson -Ddocs=enabled -Dtests=false -Dautobahn=disabled -Dpkcs11_tests=disabled -Dsysprof=%{?with_sysprof:enabled}%{?!with_sysprof:disabled} %meson_build %install @@ -78,9 +84,12 @@ install -m 644 -D tests/libsoup.supp %{buildroot}%{_datadir}/libsoup-3.0/libsoup %files help %doc README NEWS AUTHORS -%{_datadir}/doc +%doc %{_datadir}/doc/libsoup-3.0 %changelog +* Fri Jan 17 2025 Funda Wang - 3.4.5-1 +- update to 3.4.5 + * Mon Jul 21 2025 Funda Wang - 3.4.4-5 - Type:CVE - ID:CVE-2025-4476