Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libsoup2 for openSUSE:Factory 
checked in at 2026-02-24 15:37:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libsoup2 (Old)
 and      /work/SRC/openSUSE:Factory/.libsoup2.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libsoup2"

Tue Feb 24 15:37:42 2026 rev:21 rq:1334361 version:2.74.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/libsoup2/libsoup2.changes        2026-02-16 
13:23:33.177629156 +0100
+++ /work/SRC/openSUSE:Factory/.libsoup2.new.1977/libsoup2.changes      
2026-02-24 15:37:49.484488351 +0100
@@ -1,0 +2,7 @@
+Thu Feb 19 23:08:22 UTC 2026 - Michael Gorse <[email protected]>
+
+- Add libsoup2-CVE-2026-2708.patch: do not allow adding multiple
+  content length values to headers (bsc#1258508 CVE-2026-2708
+  glgo#GNOME/libsoup#500).
+
+-------------------------------------------------------------------

New:
----
  libsoup2-CVE-2026-2708.patch

----------(New B)----------
  New:
- Add libsoup2-CVE-2026-2708.patch: do not allow adding multiple
  content length values to headers (bsc#1258508 CVE-2026-2708
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libsoup2.spec ++++++
--- /var/tmp/diff_new_pack.xy2yxl/_old  2026-02-24 15:37:50.608534858 +0100
+++ /var/tmp/diff_new_pack.xy2yxl/_new  2026-02-24 15:37:50.612535025 +0100
@@ -96,6 +96,8 @@
 Patch34:        libsoup2-CVE-2026-2443.patch
 # PATCH-FIX-UPSTREAM libsoup2-CVE-2026-2369.patch bsc#1258120 [email protected] 
-- handle potential underflow in the content sniffer.
 Patch35:        libsoup2-CVE-2026-2369.patch
+# PATCH-FIX-UPSTREAM libsoup2-CVE-2026-2708.patch bsc#1258508 [email protected] 
-- do not allow adding multiple content length values to headers.
+Patch36:        libsoup2-CVE-2026-2708.patch
 
 BuildRequires:  glib-networking
 BuildRequires:  meson >= 0.50

++++++ libsoup2-CVE-2026-2708.patch ++++++
>From e032d3e9b0a27d10597398023532dd8f9b6654cf Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <[email protected]>
Date: Tue, 17 Feb 2026 16:39:26 +0100
Subject: [PATCH] Do not allow adding multiple content length values to headers

Closes #500
---
 libsoup/soup-message-headers.c | 27 ++++++++++++++
 tests/header-parsing-test.c    | 50 +++++++++++++++++++++++++-
 tests/server-test.c            | 64 ++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+), 1 deletion(-)

diff -urp libsoup-2.74.3.orig/libsoup/soup-message-headers.c 
libsoup-2.74.3/libsoup/soup-message-headers.c
--- libsoup-2.74.3.orig/libsoup/soup-message-headers.c  2026-02-19 
16:18:10.082453707 -0600
+++ libsoup-2.74.3/libsoup/soup-message-headers.c       2026-02-19 
18:40:07.082803442 -0600
@@ -206,6 +206,7 @@ soup_message_headers_append_internal (So
        SoupHeader header;
        SoupHeaderSetter setter;
        const char *interned_host = intern_header_name ("Host", NULL);
+       const char *interned_content_length = intern_header_name 
("Content-Length", NULL);
 
        g_return_val_if_fail (name != NULL, FALSE);
        g_return_val_if_fail (value != NULL, FALSE);
@@ -234,6 +235,33 @@ soup_message_headers_append_internal (So
                g_warning ("Attempted to add duplicate Host header to a 
SoupMessageHeaders that already contains a Host header");
                return FALSE;
        }
+       if (header.name == interned_content_length) {
+                /* RFC 9110 - 7.7. Content-Length
+                 * If a message is received that has a Content-Length header 
field value consisting of
+                 * the same decimal value as a comma-separated list (Section 
5.7.1) — for example,
+                 * "Content-Length: 42, 42" — indicating that duplicate 
Content-Length header fields have
+                 * been generated or combined by an upstream message 
processor, then the recipient must either
+                 * reject the message as invalid or replace the duplicated 
field values with a single valid
+                 * Content-Length field containing that decimal value prior to 
determining the message body
+                 * length or forwarding the message.
+                 */
+                const char *content_length = soup_message_headers_get_one 
(hdrs, "Content-Length");
+                if (content_length) {
+                        guint64 decimal_value1, decimal_value2;
+                        char *end;
+
+                        decimal_value1 = g_ascii_strtoull (content_length, 
&end, 10);
+                        if (*end)
+                                return FALSE;
+
+                        decimal_value2 = g_ascii_strtoull (value, &end, 10);
+                        if (*end)
+                                return FALSE;
+
+                        return (decimal_value1 == decimal_value2);
+                }
+        }
+
        header.value = g_strdup (value);
        g_array_append_val (hdrs->array, header);
        if (hdrs->concat)
diff -urp libsoup-2.74.3.orig/libsoup/soup-message-io.c 
libsoup-2.74.3/libsoup/soup-message-io.c
--- libsoup-2.74.3.orig/libsoup/soup-message-io.c       2026-02-19 
16:18:09.780755137 -0600
+++ libsoup-2.74.3/libsoup/soup-message-io.c    2026-02-19 18:39:35.257155442 
-0600
@@ -1035,7 +1035,7 @@ io_run_until (SoupMessage *msg, gboolean
        if (io->read_state == SOUP_MESSAGE_IO_STATE_DONE &&
            io->write_state == SOUP_MESSAGE_IO_STATE_DONE) {
                SoupURI *uri = soup_message_get_uri (msg);
-               char *uri_str = soup_uri_to_string (uri, FALSE);
+               char *uri_str = (uri ? soup_uri_to_string (uri, FALSE) : NULL);
                const gchar *last_modified = soup_message_headers_get_one 
(msg->request_headers, "Last-Modified");
                const gchar *etag = soup_message_headers_get_one 
(msg->request_headers, "ETag");
 
@@ -1049,7 +1049,7 @@ io_run_until (SoupMessage *msg, gboolean
                                               "Last-Modified: %s, "
                                               "ETag: %s",
                                               soup_message_get_https_status 
(msg, NULL, NULL) ? "HTTPS" : "HTTP",
-                                              uri_str, io->read_length, 
io->write_length,
+                                              (uri_str != NULL? uri_str : ""), 
io->read_length, io->write_length,
                                               (last_modified != NULL) ? 
last_modified : "(unset)",
                                               (etag != NULL) ? etag : 
"(unset)");
                g_free (uri_str);
diff -urp libsoup-2.74.3.orig/tests/header-parsing-test.c 
libsoup-2.74.3/tests/header-parsing-test.c
--- libsoup-2.74.3.orig/tests/header-parsing-test.c     2026-02-19 
16:18:09.973864096 -0600
+++ libsoup-2.74.3/tests/header-parsing-test.c  2026-02-19 17:41:55.553697085 
-0600
@@ -367,6 +367,22 @@ static struct RequestTest {
          }
        },
 
+        { "Duplicate Content-Length with the same value", NULL,
+          "POST / HTTP/1.1\r\nContent-Length: 4\r\nContent-Length: 4\r\n",
+          -1,
+          SOUP_STATUS_OK,
+          "POST", "/", SOUP_HTTP_1_1,
+          { { "Content-Length", "4" } }, 0
+        },
+
+        { "Duplicate Content-Length with the same decimal value", NULL,
+          "POST / HTTP/1.1\r\nContent-Length: 04\r\nContent-Length: 4\r\n",
+          -1,
+          SOUP_STATUS_OK,
+          "POST", "/", SOUP_HTTP_1_1,
+          { { "Content-Length", "04" } }, 0
+        },
+
        /************************/
        /*** INVALID REQUESTS ***/
        /************************/
@@ -468,6 +484,15 @@ static struct RequestTest {
          SOUP_STATUS_BAD_REQUEST,
            NULL, NULL, -1,
          { { NULL } }
+       },
+
+        { "Duplicate Content-Length with different value",
+          "https://gitlab.gnome.org/GNOME/libsoup/-/issues/500";,
+          "POST / HTTP/1.1\r\nContent-Length: 2\r\nContent-Length: 4\r\n",
+          -1,
+          SOUP_STATUS_BAD_REQUEST,
+          NULL, NULL, -1,
+          { { NULL } }, 0
        }
 };
 static const int num_reqtests = G_N_ELEMENTS (reqtests);
@@ -1306,6 +1331,28 @@ do_bad_header_tests (void)
        soup_message_headers_free (hdrs);
 }
 
+static void
+do_append_duplicate_content_length_test (void)
+{
+        SoupMessageHeaders *hdrs;
+        const char *list_value;
+
+        hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
+        soup_message_headers_append (hdrs, "Content-Length", "42");
+
+        /* Inserting the same value doesn't generate a list */
+        soup_message_headers_append (hdrs, "Content-Length", "42");
+        list_value = soup_message_headers_get_list (hdrs, "Content-Length");
+        g_assert_cmpstr (list_value, ==, "42");
+
+        /* Inserting a different value does nothing */
+        soup_message_headers_append (hdrs, "Content-Length", "45");
+        list_value = soup_message_headers_get_list (hdrs, "Content-Length");
+        g_assert_cmpstr (list_value, ==, "42");
+
+        soup_message_headers_free (hdrs);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1321,6 +1368,7 @@ main (int argc, char **argv)
        g_test_add_func ("/header-parsing/content-type", do_content_type_tests);
        g_test_add_func ("/header-parsing/append-param", do_append_param_tests);
        g_test_add_func ("/header-parsing/bad", do_bad_header_tests);
+        g_test_add_func ("/header-parsing/append-duplicate-content-length", 
do_append_duplicate_content_length_test);
 
        ret = g_test_run ();
 
diff -urp libsoup-2.74.3.orig/tests/server-test.c 
libsoup-2.74.3/tests/server-test.c
--- libsoup-2.74.3.orig/tests/server-test.c     2022-10-11 13:27:22.000000000 
-0500
+++ libsoup-2.74.3/tests/server-test.c  2026-02-19 18:42:44.517606492 -0600
@@ -1373,6 +1373,68 @@ do_steal_connect_test (ServerData *sd, g
        soup_uri_free (proxy_uri);
 }
 
+static void
+do_multiple_content_length_test (ServerData *sd, gconstpointer test_data)
+{
+        gint i;
+        struct {
+                const char *description;
+                const char *test;
+                const char *expected_response;
+        } tests[] = {
+                { "Double Content-Length with different value", "POST / 
HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nContent-Length: 
4\r\nConnection: close\r\n\r\n\r\nABCD", "HTTP/1.1 400 Bad Request" },
+                { "Double Content-Length with the same value", "POST / 
HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 4\r\nContent-Length: 
4\r\nConnection: close\r\n\r\n\r\nABCD", "HTTP/1.1 200 OK" },
+        };
+
+        sd->server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
+        sd->base_uri = soup_test_server_get_uri (sd->server, "http", NULL);
+        server_add_handler (sd, NULL, server_callback, NULL, NULL);
+
+        for (i = 0; i < G_N_ELEMENTS (tests); i++) {
+                GSocketClient *client;
+                GSocketConnection *conn;
+                GInputStream *input;
+                GOutputStream *output;
+                gsize nwritten;
+                char buffer[4096];
+                gssize nread;
+                GString *response;
+                const char *boundary;
+                GError *error = NULL;
+
+                debug_printf (1, "  %s\n", tests[i].description);
+
+                client = g_socket_client_new ();
+                conn = g_socket_client_connect_to_host (client, 
soup_uri_get_host (sd->base_uri), soup_uri_get_port (sd->base_uri), NULL, 
&error);
+                g_assert_no_error (error);
+
+                output = g_io_stream_get_output_stream (G_IO_STREAM (conn));
+                g_output_stream_write_all (output, tests[i].test, strlen 
(tests[i].test), &nwritten, NULL, &error);
+                g_assert_no_error (error);
+                g_assert_cmpuint (nwritten, ==, strlen (tests[i].test));
+                g_output_stream_flush (output, NULL, &error);
+                g_assert_no_error (error);
+
+                response = g_string_new (NULL);
+
+                input = g_io_stream_get_input_stream (G_IO_STREAM (conn));
+                do {
+                        nread = g_input_stream_read (input, buffer, 
sizeof(buffer), NULL, NULL);
+                        if (nread >= 0)
+                                response = g_string_append_len (response, 
(const char *)buffer, nread);
+                } while (nread > 0);
+
+                boundary = strstr (response->str, "\r\n");
+                g_assert_nonnull (boundary);
+                response = g_string_truncate (response, response->len - strlen 
(boundary));
+                g_assert_cmpstr (response->str, ==, 
tests[i].expected_response);
+                g_string_free (response, TRUE);
+
+                g_object_unref (conn);
+                g_object_unref (client);
+        }
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1411,6 +1473,8 @@ main (int argc, char **argv)
                    server_setup_nohandler, do_early_multi_test, 
server_teardown);
        g_test_add ("/server/steal/CONNECT", ServerData, NULL,
                    server_setup, do_steal_connect_test, server_teardown);
+        g_test_add ("/server/multiple-content-length", ServerData, NULL,
+                    NULL, do_multiple_content_length_test, server_teardown);
 
        ret = g_test_run ();
 

Reply via email to