diff --git a/backport-CVE-2024-52530.patch b/backport-CVE-2024-52530.patch deleted file mode 100644 index 2d174f2db8fdbf33bb5a1659e0997c48c95ffc3c..0000000000000000000000000000000000000000 --- a/backport-CVE-2024-52530.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 04df03bc092ac20607f3e150936624d4f536e68b Mon Sep 17 00:00:00 2001 -From: Patrick Griffis -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 - diff --git a/backport-CVE-2025-11021.patch b/backport-CVE-2025-11021.patch new file mode 100644 index 0000000000000000000000000000000000000000..59b9151e0922a4598900b5632e478d1f3e36773c --- /dev/null +++ b/backport-CVE-2025-11021.patch @@ -0,0 +1,53 @@ +From 9e1a427d2f047439d0320defe1593e6352595788 Mon Sep 17 00:00:00 2001 +From: Alynx Zhou +Date: Sat, 11 Oct 2025 15:52:47 +0800 +Subject: [PATCH] cookies: Avoid expires attribute if date is invalid + +According to CVE-2025-11021, we may get invalid on processing date +string with timezone offset, this commit will ignore it. + +Closes #459 +--- + libsoup/cookies/soup-cookie.c | 9 +++++---- + libsoup/soup-date-utils.c | 3 +++ + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libsoup/cookies/soup-cookie.c b/libsoup/cookies/soup-cookie.c +index ba949239..df446e40 100644 +--- a/libsoup/cookies/soup-cookie.c ++++ b/libsoup/cookies/soup-cookie.c +@@ -758,12 +758,13 @@ serialize_cookie (SoupCookie *cookie, GString *header, gboolean set_cookie) + + if (cookie->expires) { + char *timestamp; +- +- g_string_append (header, "; expires="); + timestamp = soup_date_time_to_string (cookie->expires, + SOUP_DATE_COOKIE); +- g_string_append (header, timestamp); +- g_free (timestamp); ++ if (timestamp) { ++ g_string_append (header, "; expires="); ++ g_string_append (header, timestamp); ++ g_free (timestamp); ++ } + } + if (cookie->path) { + g_string_append (header, "; path="); +diff --git a/libsoup/soup-date-utils.c b/libsoup/soup-date-utils.c +index 73f80ab6..71160e73 100644 +--- a/libsoup/soup-date-utils.c ++++ b/libsoup/soup-date-utils.c +@@ -95,6 +95,9 @@ soup_date_time_to_string (GDateTime *date, + char *date_format; + char *formatted_date; + ++ if (!utcdate) ++ return NULL; ++ + // We insert days/months ourselves to avoid locale specific formatting + if (format == SOUP_DATE_HTTP) { + /* "Sun, 06 Nov 1994 08:49:37 GMT" */ +-- +GitLab + diff --git a/backport-CVE-2025-12105.patch b/backport-CVE-2025-12105.patch new file mode 100644 index 0000000000000000000000000000000000000000..fe1142da825f21595f72dd23df3362482fff8273 --- /dev/null +++ b/backport-CVE-2025-12105.patch @@ -0,0 +1,30 @@ +From 9ba1243a24e442fa5ec44684617a4480027da960 Mon Sep 17 00:00:00 2001 +From: Eugene Mutavchi +Date: Fri, 10 Oct 2025 16:24:27 +0000 +Subject: [PATCH] fix 'heap-use-after-free' caused by 'finishing' queue item + twice + +--- + libsoup/soup-session.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c +index c5694d2c..4e6b478b 100644 +--- a/libsoup/soup-session.c ++++ b/libsoup/soup-session.c +@@ -2894,8 +2894,10 @@ run_until_read_done (SoupMessage *msg, + if (soup_message_io_in_progress (msg)) + soup_message_io_finished (msg); + item->paused = FALSE; +- item->state = SOUP_MESSAGE_FINISHING; +- soup_session_process_queue_item (item->session, item, FALSE); ++ if (item->state != SOUP_MESSAGE_FINISHED) { ++ item->state = SOUP_MESSAGE_FINISHING; ++ soup_session_process_queue_item (item->session, item, FALSE); ++ } + } + async_send_request_return_result (item, NULL, error); + soup_message_queue_item_unref (item); +-- +GitLab + diff --git a/backport-CVE-2025-32907.patch b/backport-CVE-2025-32907.patch new file mode 100644 index 0000000000000000000000000000000000000000..01c36f6e353093335c6d476a42233867e46c7b85 --- /dev/null +++ b/backport-CVE-2025-32907.patch @@ -0,0 +1,259 @@ +From 9bb92f7a685e31e10e9e8221d0342280432ce836 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Tue, 15 Apr 2025 12:17:39 +0200 +Subject: [PATCH 1/2] soup-message-headers: Correct merge of ranges + +It had been skipping every second range, which generated an array +of a lot of insane ranges, causing large memory usage by the server. + +Closes #428 + +Part-of: +--- + libsoup/soup-message-headers.c | 1 + + tests/meson.build | 1 + + tests/server-mem-limit-test.c | 144 +++++++++++++++++++++++++++++++++ + 3 files changed, 146 insertions(+) + create mode 100644 tests/server-mem-limit-test.c + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index 8eec4200..e799082b 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1244,6 +1244,7 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + if (cur->start <= prev->end) { + prev->end = MAX (prev->end, cur->end); + g_array_remove_index (array, i); ++ i--; + } + } + } +diff --git a/tests/meson.build b/tests/meson.build +index 02924c03..ac892359 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -103,6 +103,7 @@ tests = [ + {'name': 'samesite'}, + {'name': 'session'}, + {'name': 'server-auth'}, ++ {'name': 'server-mem-limit'}, + {'name': 'server'}, + {'name': 'sniffing', + 'depends': [test_resources], +diff --git a/tests/server-mem-limit-test.c b/tests/server-mem-limit-test.c +new file mode 100644 +index 00000000..98f1c40f +--- /dev/null ++++ b/tests/server-mem-limit-test.c +@@ -0,0 +1,144 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ ++/* ++ * Copyright (C) 2025 Red Hat ++ */ ++ ++#include "test-utils.h" ++ ++#include ++ ++/* ++ This test limits memory usage to trigger too large buffer allocation crash. ++ As restoring the limits back to what it was does not always work, it's split ++ out of the server-test.c test with copied minimal server code. ++ */ ++ ++typedef struct { ++ SoupServer *server; ++ GUri *base_uri, *ssl_base_uri; ++ GSList *handlers; ++} ServerData; ++ ++static void ++server_setup_nohandler (ServerData *sd, gconstpointer test_data) ++{ ++ sd->server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); ++ sd->base_uri = soup_test_server_get_uri (sd->server, "http", NULL); ++ if (tls_available) ++ sd->ssl_base_uri = soup_test_server_get_uri (sd->server, "https", NULL); ++} ++ ++static void ++server_add_handler (ServerData *sd, ++ const char *path, ++ SoupServerCallback callback, ++ gpointer user_data, ++ GDestroyNotify destroy) ++{ ++ soup_server_add_handler (sd->server, path, callback, user_data, destroy); ++ sd->handlers = g_slist_prepend (sd->handlers, g_strdup (path)); ++} ++ ++static void ++server_setup (ServerData *sd, gconstpointer test_data) ++{ ++ server_setup_nohandler (sd, test_data); ++} ++ ++static void ++server_teardown (ServerData *sd, gconstpointer test_data) ++{ ++ GSList *iter; ++ ++ for (iter = sd->handlers; iter; iter = iter->next) ++ soup_server_remove_handler (sd->server, iter->data); ++ g_slist_free_full (sd->handlers, g_free); ++ ++ g_clear_pointer (&sd->server, soup_test_server_quit_unref); ++ g_clear_pointer (&sd->base_uri, g_uri_unref); ++ g_clear_pointer (&sd->ssl_base_uri, g_uri_unref); ++} ++ ++static void ++server_file_callback (SoupServer *server, ++ SoupServerMessage *msg, ++ const char *path, ++ GHashTable *query, ++ gpointer data) ++{ ++ void *mem; ++ ++ g_assert_cmpstr (path, ==, "/file"); ++ g_assert_cmpstr (soup_server_message_get_method (msg), ==, SOUP_METHOD_GET); ++ ++ mem = g_malloc0 (sizeof (char) * 1024 * 1024); ++ /* fedora-scan CI claims a warning about possibly leaked `mem` variable, thus use ++ the copy and free it explicitly, to workaround the false positive; the g_steal_pointer() ++ did not help for the malloc-ed memory */ ++ soup_server_message_set_response (msg, "application/octet-stream", SOUP_MEMORY_COPY, mem, sizeof (char) * 1024 *1024); ++ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); ++ g_free (mem); ++} ++ ++static void ++do_ranges_overlaps_test (ServerData *sd, gconstpointer test_data) ++{ ++ SoupSession *session; ++ SoupMessage *msg; ++ GString *range; ++ GUri *uri; ++ const char *chunk = ",0,0,0,0,0,0,0,0,0,0,0"; ++ ++ g_test_bug ("428"); ++ ++ #ifdef G_OS_WIN32 ++ g_test_skip ("Cannot run under windows"); ++ return; ++ #endif ++ ++ range = g_string_sized_new (99 * 1024); ++ g_string_append (range, "bytes=1024"); ++ while (range->len < 99 * 1024) ++ g_string_append (range, chunk); ++ ++ session = soup_test_session_new (NULL); ++ server_add_handler (sd, "/file", server_file_callback, NULL, NULL); ++ ++ uri = g_uri_parse_relative (sd->base_uri, "/file", SOUP_HTTP_URI_FLAGS, NULL); ++ ++ msg = soup_message_new_from_uri ("GET", uri); ++ soup_message_headers_append (soup_message_get_request_headers (msg), "Range", range->str); ++ ++ soup_test_session_send_message (session, msg); ++ ++ soup_test_assert_message_status (msg, SOUP_STATUS_PARTIAL_CONTENT); ++ ++ g_object_unref (msg); ++ ++ g_string_free (range, TRUE); ++ g_uri_unref (uri); ++ ++ soup_test_session_abort_unref (session); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int ret; ++ ++ test_init (argc, argv, NULL); ++ ++ #ifndef G_OS_WIN32 ++ struct rlimit new_rlimit = { 1024 * 1024 * 64, 1024 * 1024 * 64 }; ++ /* limit memory usage, to trigger too large memory allocation abort */ ++ g_assert_cmpint (setrlimit (RLIMIT_DATA, &new_rlimit), ==, 0); ++ #endif ++ ++ g_test_add ("/server-mem/range-overlaps", ServerData, NULL, ++ server_setup, do_ranges_overlaps_test, server_teardown); ++ ++ ret = g_test_run (); ++ ++ test_cleanup (); ++ return ret; ++} +-- +GitLab + + +From eeace39ec686094ff6a05a43e5fce06e9c37f376 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Tue, 13 May 2025 14:20:46 +0200 +Subject: [PATCH 2/2] server-mem-limit-test: Limit memory usage only when not + built witha sanitizer + +A build with -Db_sanitize=address crashes with failed mmap(), which is done +inside libasan. The test requires 20.0TB of virtual memory when running with +the sanitizer, which is beyond unsigned integer limits and may not trigger +the bug anyway. + +Part-of: +--- + meson.build | 4 ++++ + tests/server-mem-limit-test.c | 13 +++++++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/meson.build b/meson.build +index 8772a0ea..b31a8791 100644 +--- a/meson.build ++++ b/meson.build +@@ -357,6 +357,10 @@ configinc = include_directories('.') + + prefix = get_option('prefix') + ++if get_option('b_sanitize') != 'none' ++ cdata.set_quoted('B_SANITIZE_OPTION', get_option('b_sanitize')) ++endif ++ + cdata.set_quoted('PACKAGE_VERSION', soup_version) + cdata.set_quoted('LOCALEDIR', join_paths(prefix, get_option('localedir'))) + cdata.set_quoted('GETTEXT_PACKAGE', libsoup_api_name) +diff --git a/tests/server-mem-limit-test.c b/tests/server-mem-limit-test.c +index 98f1c40f..65dc875e 100644 +--- a/tests/server-mem-limit-test.c ++++ b/tests/server-mem-limit-test.c +@@ -126,14 +126,19 @@ main (int argc, char **argv) + { + int ret; + +- test_init (argc, argv, NULL); +- +- #ifndef G_OS_WIN32 +- struct rlimit new_rlimit = { 1024 * 1024 * 64, 1024 * 1024 * 64 }; ++ /* a build with an address sanitizer may crash on mmap() with the limit, ++ thus skip the limit set in such case, even it may not necessarily ++ trigger the bug if it regresses */ ++ #if !defined(G_OS_WIN32) && !defined(B_SANITIZE_OPTION) ++ struct rlimit new_rlimit = { 1024UL * 1024UL * 1024UL * 2UL, 1024UL * 1024UL * 1024UL * 2UL }; + /* limit memory usage, to trigger too large memory allocation abort */ + g_assert_cmpint (setrlimit (RLIMIT_DATA, &new_rlimit), ==, 0); ++ #else ++ g_message ("server-mem-limit-test: Running without memory limit"); + #endif + ++ test_init (argc, argv, NULL); ++ + g_test_add ("/server-mem/range-overlaps", ServerData, NULL, + server_setup, do_ranges_overlaps_test, server_teardown); + +-- +GitLab + diff --git a/libsoup-3.4.5.tar.xz b/libsoup-3.4.5.tar.xz deleted file mode 100644 index edb5ad7f1ba66e3e3141a855d7a3c0e2dc540585..0000000000000000000000000000000000000000 Binary files a/libsoup-3.4.5.tar.xz and /dev/null differ diff --git a/libsoup-3.6.5.tar.xz b/libsoup-3.6.5.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..10df9e3ae6241072c4a7b7bea156c703d8992f27 Binary files /dev/null and b/libsoup-3.6.5.tar.xz differ diff --git a/libsoup3.spec b/libsoup3.spec index d21e9e01794112824c37f5c82da322ce9ec10f5c..9cae57dd69d816199d6efff1f9780555b95ea5f8 100644 --- a/libsoup3.spec +++ b/libsoup3.spec @@ -1,17 +1,19 @@ -%global glib2_version 2.69.1 +%global glib2_version 2.70.0 %bcond_without sysprof Name: libsoup3 -Version: 3.4.5 +Version: 3.6.5 Release: 1 Summary: Soup, an HTTP library implementation 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 +Source0: https://download.gnome.org/sources/libsoup/%{version_major_minor}/libsoup-%{version}.tar.xz -Patch0002: backport-CVE-2024-52530.patch -Patch0004: backport-CVE-2025-4476.patch +Patch6001: backport-CVE-2025-4476.patch +Patch6002: backport-CVE-2025-12105.patch +Patch6003: backport-CVE-2025-11021.patch +Patch6004: backport-CVE-2025-32907.patch BuildRequires: gcc gettext vala krb5-devel samba-winbind-clients BuildRequires: meson >= 0.54 @@ -87,6 +89,9 @@ install -m 644 -D tests/libsoup.supp %{buildroot}%{_datadir}/libsoup-3.0/libsoup %doc %{_datadir}/doc/libsoup-3.0 %changelog +* Sun Oct 26 2025 Funda Wang - 3.6.5-1 +- update to 3.6.5 + * Fri Jan 17 2025 Funda Wang - 3.4.5-1 - update to 3.4.5