From f1cece661459765c1df3aa59a3a1801e64b213f0 Mon Sep 17 00:00:00 2001 From: Azure Linux Security Servicing Account Date: Tue, 17 Feb 2026 02:53:46 +0000 Subject: [PATCH 1/5] Patch libsoup for CVE-2026-1760 --- SPECS/libsoup/CVE-2026-1760.patch | 159 ++++++++++++++++++++++++++++++ SPECS/libsoup/libsoup.spec | 6 +- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 SPECS/libsoup/CVE-2026-1760.patch diff --git a/SPECS/libsoup/CVE-2026-1760.patch b/SPECS/libsoup/CVE-2026-1760.patch new file mode 100644 index 00000000000..0f596c9bbac --- /dev/null +++ b/SPECS/libsoup/CVE-2026-1760.patch @@ -0,0 +1,159 @@ +From 3dbb793d73f7aa0be3dde72a44877c16698dee5c Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Tue, 17 Feb 2026 02:44:11 +0000 +Subject: [PATCH] server: close the connection after responsing a request + containing Content-Length and Transfer-Encoding + +Closes #475 + +- Recompute encoding lazily prioritizing Transfer-Encoding over Content-Length. +- Ensure server closes connection when both headers are present by setting Connection: close. + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport of https://gitlab.gnome.org/GNOME/libsoup/-/commit/30b682af333402eeef4fad3acbc865771f85281a.patch +--- + libsoup/server/soup-server-io.c | 9 ++++ + libsoup/soup-message-headers.c | 88 +++++++++++++++------------------ + 2 files changed, 50 insertions(+), 47 deletions(-) + +diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c +index 7e9cc45..0efb9b7 100644 +--- a/libsoup/server/soup-server-io.c ++++ b/libsoup/server/soup-server-io.c +@@ -599,6 +599,15 @@ parse_headers (SoupServerMessage *msg, + return SOUP_STATUS_BAD_REQUEST; + } + ++ /* A server MAY reject a request that contains both Content-Length and ++ * Transfer-Encoding or process such a request in accordance with the ++ * Transfer-Encoding alone. Regardless, the server MUST close the connection ++ * after responding to such a request to avoid the potential attacks ++ */ ++ if (*encoding == SOUP_ENCODING_CHUNKED && soup_message_headers_get_one_common (request_headers, SOUP_HEADER_CONTENT_LENGTH)) ++ soup_message_headers_replace_common (request_headers, SOUP_HEADER_CONNECTION, "close", TRUE); ++ ++ + /* Generate correct context for request */ + req_host = soup_message_headers_get_one_common (request_headers, SOUP_HEADER_HOST); + if (req_host && strchr (req_host, '/')) { +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index d71a2cf..1a6be25 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -155,19 +155,8 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, + { + switch (name) { + case SOUP_HEADER_CONTENT_LENGTH: +- if (hdrs->encoding == SOUP_ENCODING_CHUNKED) +- return; +- +- if (value) { +- char *end; +- +- hdrs->content_length = g_ascii_strtoull (value, &end, 10); +- if (*end) +- hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; +- else +- hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; +- } else +- hdrs->encoding = -1; ++ case SOUP_HEADER_TRANSFER_ENCODING: ++ hdrs->encoding = -1; + break; + case SOUP_HEADER_CONTENT_TYPE: + g_clear_pointer (&hdrs->content_type, g_free); +@@ -193,21 +182,7 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, + } else + hdrs->expectations = 0; + break; +- case SOUP_HEADER_TRANSFER_ENCODING: +- if (value) { +- /* "identity" is a wrong value according to RFC errata 408, +- * and RFC 7230 does not list it as valid transfer-coding. +- * Nevertheless, the obsolete RFC 2616 stated "identity" +- * as valid, so we can't handle it as unrecognized here +- * for compatibility reasons. +- */ +- if (g_ascii_strcasecmp (value, "chunked") == 0) +- hdrs->encoding = SOUP_ENCODING_CHUNKED; +- else if (g_ascii_strcasecmp (value, "identity") != 0) +- hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; +- } else +- hdrs->encoding = -1; +- break; ++ /* SOUP_HEADER_TRANSFER_ENCODING handled by recomputing encoding lazily */ + default: + break; + } +@@ -951,30 +926,49 @@ soup_message_headers_foreach (SoupMessageHeaders *hdrs, + SoupEncoding + soup_message_headers_get_encoding (SoupMessageHeaders *hdrs) + { +- const char *header; ++ const char *content_length; ++ const char *transfer_encoding; + + if (hdrs->encoding != -1) + return hdrs->encoding; + +- /* If Transfer-Encoding was set, hdrs->encoding would already +- * be set. So we don't need to check that possibility. +- */ +- header = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_CONTENT_LENGTH); +- if (header) { +- soup_message_headers_set (hdrs, SOUP_HEADER_CONTENT_LENGTH, header); +- if (hdrs->encoding != -1) +- return hdrs->encoding; +- } ++ /* Transfer-Encoding is checked first because it overrides the Content-Length */ ++ transfer_encoding = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_TRANSFER_ENCODING); ++ if (transfer_encoding) { ++ /* "identity" is a wrong value according to RFC errata 408, ++ * and RFC 7230 does not list it as valid transfer-coding. ++ * Nevertheless, the obsolete RFC 2616 stated "identity" ++ * as valid, so we can't handle it as unrecognized here ++ * for compatibility reasons. ++ */ ++ if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) ++ hdrs->encoding = SOUP_ENCODING_CHUNKED; ++ else if (g_ascii_strcasecmp (transfer_encoding, "identity") != 0) ++ hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; ++ } else { ++ content_length = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_CONTENT_LENGTH); ++ if (content_length) { ++ char *end; + +- /* Per RFC 2616 4.4, a response body that doesn't indicate its +- * encoding otherwise is terminated by connection close, and a +- * request that doesn't indicate otherwise has no body. Note +- * that SoupMessage calls soup_message_headers_set_encoding() +- * to override the response body default for our own +- * server-side messages. +- */ +- hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? +- SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; ++ hdrs->content_length = g_ascii_strtoull (content_length, &end, 10); ++ if (*end) ++ hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; ++ else ++ hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; ++ } ++ } ++ ++ if (hdrs->encoding == -1) { ++ /* Per RFC 2616 4.4, a response body that doesn't indicate its ++ * encoding otherwise is terminated by connection close, and a ++ * request that doesn't indicate otherwise has no body. Note ++ * that SoupMessage calls soup_message_headers_set_encoding() ++ * to override the response body default for our own ++ * server-side messages. ++ */ ++ hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? ++ SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; ++ } + return hdrs->encoding; + } + +-- +2.45.4 + diff --git a/SPECS/libsoup/libsoup.spec b/SPECS/libsoup/libsoup.spec index 685c43945aa..b033a47d026 100644 --- a/SPECS/libsoup/libsoup.spec +++ b/SPECS/libsoup/libsoup.spec @@ -2,7 +2,7 @@ Summary: libsoup HTTP client/server library Name: libsoup Version: %{BaseVersion}.4 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv2 Vendor: Microsoft Corporation Distribution: Mariner @@ -38,6 +38,7 @@ Patch19: CVE-2025-4969.patch Patch20: CVE-2025-11021.patch Patch21: CVE-2025-32049.patch Patch22: CVE-2026-1536.patch +Patch23: CVE-2026-1760.patch BuildRequires: meson @@ -150,6 +151,9 @@ find %{buildroot} -type f -name "*.la" -delete -print %defattr(-,root,root) %changelog +* Tue Feb 17 2026 Azure Linux Security Servicing Account - 3.0.4-12 +- Patch for CVE-2026-1760 + * Thu Feb 12 2026 Jyoti Kanase - 3.0.4-11 - Patch for CVE-2025-32049, CVE-2025-1536 From bca0e0d5d67d9ad5dd41f280659370fc985daf72 Mon Sep 17 00:00:00 2001 From: Azure Linux Security Servicing Account Date: Fri, 20 Feb 2026 07:00:15 +0000 Subject: [PATCH 2/5] Patch libsoup for CVE-2026-2443 --- SPECS/libsoup/CVE-2026-2443.patch | 340 ++++++++++++++++++++++++++++++ SPECS/libsoup/libsoup.spec | 3 +- 2 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 SPECS/libsoup/CVE-2026-2443.patch diff --git a/SPECS/libsoup/CVE-2026-2443.patch b/SPECS/libsoup/CVE-2026-2443.patch new file mode 100644 index 00000000000..9cbd802d7f1 --- /dev/null +++ b/SPECS/libsoup/CVE-2026-2443.patch @@ -0,0 +1,340 @@ +From 61d80f22c9117d6d73c20d506346a2e9a4d5d42b Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 19 Dec 2025 23:49:05 +0000 +Subject: [PATCH 1/7] soup-message-headers: Reject invalid Range ends longer + than the content + +If the `Range` header in a request specifies a range longer than the +full content, it should be rejected. Previously, only the start of the +range was validated, rather than the start and the end. This led to an +assertion failure in `g_bytes_new_from_bytes()` (or a buffer overflow if +GLib was compiled with `G_DISABLE_CHECKS`, which is not recommended). + +Add the missing check on the Range end, and add a unit test. + +Spotted by Codean Labs. + +Signed-off-by: Philip Withnall + +Fixes: #487 +--- + libsoup/soup-message-headers.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index 1a6be25..f869bac 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1203,7 +1203,9 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + if (*end) { + status = SOUP_STATUS_OK; + break; +- } else if (check_satisfiable && cur.start >= total_length) { ++ } else if (check_satisfiable && ++ (cur.start >= total_length || ++ cur.end >= total_length)) { + if (status == SOUP_STATUS_OK) + status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; + continue; +-- +2.45.4 + + +From 24a1aa4270ae60c125354a5dda5d28fd9e5aff2d Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 19 Dec 2025 23:51:52 +0000 +Subject: [PATCH 2/7] soup-message-headers: Reject ranges where end is before + start + +Previously this returned HTTP status 200 OK, which is not what MDN says +should happen for an invalid range: +https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Range. + +Add a unit test. + +Signed-off-by: Philip Withnall +--- + libsoup/soup-message-headers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index f869bac..3c07207 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1194,7 +1194,7 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + if (*end) { + cur.end = g_ascii_strtoull (end, &end, 10); + if (cur.end < cur.start) { +- status = SOUP_STATUS_OK; ++ status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; + break; + } + } else +-- +2.45.4 + + +From db5bf089791da03f4fc566a8c9f890376e10776c Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Sat, 20 Dec 2025 00:14:00 +0000 +Subject: [PATCH 3/7] soup-message-headers: Fix parsing of invalid Range suffix + lengths + +The way the parser for the `Range` header is implemented, this would +result in a range with an end 1 byte before its start. + +Add a unit test. + +Signed-off-by: Philip Withnall +--- + libsoup/soup-message-headers.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index 3c07207..6450ef9 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1187,6 +1187,10 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + if (*spec == '-') { + cur.start = g_ascii_strtoll (spec, &end, 10) + total_length; + cur.end = total_length - 1; ++ if (cur.end < cur.start) { ++ status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; ++ break; ++ } + } else { + cur.start = g_ascii_strtoull (spec, &end, 10); + if (*end == '-') +-- +2.45.4 + + +From 98f252c826ef11fcaf74a0c51c2eab59c95bc9e9 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Sat, 20 Dec 2025 00:18:25 +0000 +Subject: [PATCH 4/7] soup-message-headers: Fix rejection of Range headers with + trailing garbage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If there’s unparseable content after a range, reject the header as +invalid rather than ignoring it and returning status 200 OK. + +Add a unit test. + +Signed-off-by: Philip Withnall +--- + libsoup/soup-message-headers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index 6450ef9..2752420 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1205,7 +1205,7 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + cur.end = total_length - 1; + } + if (*end) { +- status = SOUP_STATUS_OK; ++ status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; + break; + } else if (check_satisfiable && + (cur.start >= total_length || +-- +2.45.4 + + +From 7916ba538ebd5c15b5b46f7e5ea6c405d2726270 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 25 Dec 2025 23:16:02 +0000 +Subject: [PATCH 5/7] tests: Allow range tests to check more response statuses + +Currently the tests can either assert that a response to a Range request +is HTTP 206 (Partial Content) or HTTP 416 (Range Not Satisfiable). +However, many of the states resulting from parsing a Range header +actually should have a HTTP 200 (OK) response, where the Range header is +ignored due to being completely invalid. This is what Apache does when, +for example, given a Range header where the end of the range is before +the start. + +Add some extra arguments to the helper functions in `range-test.c` to +allow the expected response status and expected response start and end +(of the full response) to be given by the test, and change the existing +tests to use these extra arguments. + +This introduces no behavioural changes for now, but will allow following +commits to test their status 200 responses. + +Signed-off-by: Philip Withnall +-- +2.45.4 + + +From f638a577e497c3e84fb86d56035ac44e465c3748 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 25 Dec 2025 23:20:03 +0000 +Subject: [PATCH 6/7] soup-message-headers: Rework Range response statuses to + match Apache + +And for the parsing logic to more closely match the wording of the +HTTP specification (https://httpwg.org/specs/rfc9110.html#field.range). + +The previous behaviour (from my previous few commits) was potentially +correct according to the spec, but differed from what Apache implements, +so was inadvisable. Specifically, the code returned HTTP 416 for various +parsing errors on the Range header; whereas Apache ignores completely +invalid Range headers and returns HTTP 200 with the full response. For +partially invalid Range headers, it returns the valid ranges. + +Implement that behaviour instead, and rework the structure of the Range +parsing code to (hopefully) make that intent clearer. For example, +separate the string parsing code from the numeric range checks, and +separate those from the decision about which HTTP status to return. + +Signed-off-by: Philip Withnall + +Helps: #487 +--- + libsoup/soup-message-headers.c | 68 ++++++++++++++++++++++------------ + 1 file changed, 44 insertions(+), 24 deletions(-) + +diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c +index 2752420..d208191 100644 +--- a/libsoup/soup-message-headers.c ++++ b/libsoup/soup-message-headers.c +@@ -1146,10 +1146,16 @@ sort_ranges (gconstpointer a, gconstpointer b) + } + + /* like soup_message_headers_get_ranges(), except it returns: +- * SOUP_STATUS_OK if there is no Range or it should be ignored. +- * SOUP_STATUS_PARTIAL_CONTENT if there is at least one satisfiable range. +- * SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE if @check_satisfiable +- * is %TRUE and the request is not satisfiable given @total_length. ++ * - SOUP_STATUS_OK if there is no Range or it should be ignored due to being ++ * entirely invalid. ++ * - SOUP_STATUS_PARTIAL_CONTENT if there is at least one satisfiable range. ++ * - SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE if @check_satisfiable ++ * is %TRUE, the Range is valid, but no part of the request is satisfiable ++ * given @total_length. ++ * ++ * @ranges and @length are only set if SOUP_STATUS_PARTIAL_CONTENT is returned. ++ * ++ * See https://httpwg.org/specs/rfc9110.html#field.range + */ + guint + soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, +@@ -1163,22 +1169,28 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + GArray *array; + char *spec, *end; + guint status = SOUP_STATUS_OK; ++ gboolean is_all_valid = TRUE; + + if (!range || strncmp (range, "bytes", 5) != 0) +- return status; ++ return SOUP_STATUS_OK; /* invalid header or unknown range unit */ + + range += 5; + while (g_ascii_isspace (*range)) + range++; + if (*range++ != '=') +- return status; ++ return SOUP_STATUS_OK; /* invalid header */ + while (g_ascii_isspace (*range)) + range++; + + range_list = soup_header_parse_list (range); + if (!range_list) +- return status; ++ return SOUP_STATUS_OK; /* invalid list */ + ++ /* Loop through the ranges and modify the status accordingly. Default to ++ * status 200 (OK, ignoring the ranges). Switch to status 206 (Partial ++ * Content) if there is at least one partially valid range. Switch to ++ * status 416 (Range Not Satisfiable) if there are no partially valid ++ * ranges at all. */ + array = g_array_new (FALSE, FALSE, sizeof (SoupRange)); + for (r = range_list; r; r = r->next) { + SoupRange cur; +@@ -1187,40 +1199,48 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs, + if (*spec == '-') { + cur.start = g_ascii_strtoll (spec, &end, 10) + total_length; + cur.end = total_length - 1; +- if (cur.end < cur.start) { +- status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; +- break; +- } + } else { + cur.start = g_ascii_strtoull (spec, &end, 10); + if (*end == '-') + end++; +- if (*end) { ++ if (*end) + cur.end = g_ascii_strtoull (end, &end, 10); +- if (cur.end < cur.start) { +- status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; +- break; +- } +- } else ++ else + cur.end = total_length - 1; + } ++ + if (*end) { +- status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; +- break; +- } else if (check_satisfiable && +- (cur.start >= total_length || +- cur.end >= total_length)) { +- if (status == SOUP_STATUS_OK) +- status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; ++ /* Junk after the range */ ++ is_all_valid = FALSE; + continue; + } + ++ if (cur.end < cur.start) { ++ is_all_valid = FALSE; ++ continue; ++ } ++ ++ g_assert (cur.start >= 0); ++ if (cur.end >= total_length) ++ cur.end = total_length - 1; ++ ++ if (cur.start >= total_length) { ++ /* Range is valid, but unsatisfiable */ ++ continue; ++ } ++ ++ /* We have at least one (at least partially) satisfiable range */ + g_array_append_val (array, cur); + status = SOUP_STATUS_PARTIAL_CONTENT; + } + soup_header_free_list (range_list); + + if (status != SOUP_STATUS_PARTIAL_CONTENT) { ++ g_assert (status == SOUP_STATUS_OK); ++ ++ if (is_all_valid && check_satisfiable) ++ status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; ++ + g_array_free (array, TRUE); + return status; + } +-- +2.45.4 + + +From 2f462883ba2130170aae68bc27b20faa21cc5a6b Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 25 Dec 2025 23:50:30 +0000 +Subject: [PATCH 7/7] tests: Add more tests for invalid Range headers + +This gives full line and branch coverage of +`soup_message_headers_get_ranges_internal()`. + +Signed-off-by: Philip Withnall +-- +2.45.4 + diff --git a/SPECS/libsoup/libsoup.spec b/SPECS/libsoup/libsoup.spec index e1cb45353ca..02a149ffc0e 100644 --- a/SPECS/libsoup/libsoup.spec +++ b/SPECS/libsoup/libsoup.spec @@ -40,6 +40,7 @@ Patch21: CVE-2025-32049.patch Patch22: CVE-2026-1536.patch Patch23: CVE-2026-0716.patch Patch24: CVE-2026-1760.patch +Patch25: CVE-2026-2443.patch BuildRequires: meson @@ -153,7 +154,7 @@ find %{buildroot} -type f -name "*.la" -delete -print %changelog * Tue Feb 17 2026 Azure Linux Security Servicing Account - 3.0.4-13 -- Patch for CVE-2026-1760 +- Patch for CVE-2026-1760, CVE-2026-2443 * Tue Feb 17 2026 Azure Linux Security Servicing Account - 3.0.4-12 - Patch for CVE-2026-0716 From 2c7222216df4cad8d842d84287382479ca0a89b5 Mon Sep 17 00:00:00 2001 From: Azure Linux Security Servicing Account Date: Wed, 25 Mar 2026 09:24:11 +0000 Subject: [PATCH 3/5] Patch libsoup for CVE-2026-2369 --- SPECS/libsoup/CVE-2026-2369.patch | 31 +++++++++++++++++++++++++++++++ SPECS/libsoup/libsoup.spec | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 SPECS/libsoup/CVE-2026-2369.patch diff --git a/SPECS/libsoup/CVE-2026-2369.patch b/SPECS/libsoup/CVE-2026-2369.patch new file mode 100644 index 00000000000..42a9eca8fde --- /dev/null +++ b/SPECS/libsoup/CVE-2026-2369.patch @@ -0,0 +1,31 @@ +From 7f618da093133bf7ff5821c74a13a800a6cf6452 Mon Sep 17 00:00:00 2001 +From: Samuel Dainard <> +Date: Wed, 11 Feb 2026 10:19:04 -0600 +Subject: [PATCH] sniffer: Handle potential underflow + +Closes #498 + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://gitlab.gnome.org/GNOME/libsoup/-/commit/af4bde990270b825b7d110a495cc65de9e2ec32f.patch +--- + libsoup/content-sniffer/soup-content-sniffer.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c +index 3d0e831..914b5b4 100644 +--- a/libsoup/content-sniffer/soup-content-sniffer.c ++++ b/libsoup/content-sniffer/soup-content-sniffer.c +@@ -521,6 +521,10 @@ sniff_unknown (SoupContentSniffer *sniffer, GBytes *buffer, + if (!sniff_scriptable && type_row->scriptable) + continue; + ++ /* Ensure we have data to sniff - prevents underflow in resource_length - 1 */ ++ if (resource_length == 0) ++ continue; ++ + if (type_row->has_ws) { + guint index_stream = 0; + guint index_pattern = 0; +-- +2.45.4 + diff --git a/SPECS/libsoup/libsoup.spec b/SPECS/libsoup/libsoup.spec index 9adcade0c21..55378cae19e 100644 --- a/SPECS/libsoup/libsoup.spec +++ b/SPECS/libsoup/libsoup.spec @@ -44,6 +44,7 @@ Patch25: CVE-2026-1761.patch Patch26: CVE-2026-1801.patch Patch27: CVE-2026-1760.patch Patch28: CVE-2026-2443.patch +Patch29: CVE-2026-2369.patch BuildRequires: meson @@ -157,7 +158,7 @@ find %{buildroot} -type f -name "*.la" -delete -print %changelog * Tue Feb 17 2026 Azure Linux Security Servicing Account - 3.0.4-14 -- Patch for CVE-2026-1760, CVE-2026-2443 +- Patch for CVE-2026-1760, CVE-2026-2443, CVE-2026-2369 * Mon Feb 16 2026 Azure Linux Security Servicing Account - 3.0.4-13 - Patch for CVE-2026-1801, CVE-2026-1761, CVE-2026-1467 From e04ef730789e04cf7a498f1b312a160fb1d892a1 Mon Sep 17 00:00:00 2001 From: jykanase Date: Wed, 25 Mar 2026 13:35:35 +0000 Subject: [PATCH 4/5] added test file changes to CVE-2026-1760 --- SPECS/libsoup/CVE-2026-1760.patch | 92 +++++++++++++++++-------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/SPECS/libsoup/CVE-2026-1760.patch b/SPECS/libsoup/CVE-2026-1760.patch index 0f596c9bbac..dea10bcc7e1 100644 --- a/SPECS/libsoup/CVE-2026-1760.patch +++ b/SPECS/libsoup/CVE-2026-1760.patch @@ -1,26 +1,23 @@ -From 3dbb793d73f7aa0be3dde72a44877c16698dee5c Mon Sep 17 00:00:00 2001 -From: AllSpark -Date: Tue, 17 Feb 2026 02:44:11 +0000 +From 30b682af333402eeef4fad3acbc865771f85281a Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Thu, 29 Jan 2026 16:43:28 +0100 Subject: [PATCH] server: close the connection after responsing a request containing Content-Length and Transfer-Encoding Closes #475 -- Recompute encoding lazily prioritizing Transfer-Encoding over Content-Length. -- Ensure server closes connection when both headers are present by setting Connection: close. - -Signed-off-by: Azure Linux Security Servicing Account -Upstream-reference: AI Backport of https://gitlab.gnome.org/GNOME/libsoup/-/commit/30b682af333402eeef4fad3acbc865771f85281a.patch +Upstream Patch Reference: https://gitlab.gnome.org/GNOME/libsoup/-/commit/30b682af333402eeef4fad3acbc865771f85281a.patch --- - libsoup/server/soup-server-io.c | 9 ++++ - libsoup/soup-message-headers.c | 88 +++++++++++++++------------------ - 2 files changed, 50 insertions(+), 47 deletions(-) + libsoup/server/soup-server-io.c | 8 +++ + libsoup/soup-message-headers.c | 86 +++++++++++++++------------------ + tests/server-test.c | 4 +- + 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c -index 7e9cc45..0efb9b7 100644 +index 7e9cc45..9e237a3 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c -@@ -599,6 +599,15 @@ parse_headers (SoupServerMessage *msg, +@@ -599,6 +599,14 @@ parse_headers (SoupServerMessage *msg, return SOUP_STATUS_BAD_REQUEST; } @@ -31,13 +28,12 @@ index 7e9cc45..0efb9b7 100644 + */ + if (*encoding == SOUP_ENCODING_CHUNKED && soup_message_headers_get_one_common (request_headers, SOUP_HEADER_CONTENT_LENGTH)) + soup_message_headers_replace_common (request_headers, SOUP_HEADER_CONNECTION, "close", TRUE); -+ + /* Generate correct context for request */ req_host = soup_message_headers_get_one_common (request_headers, SOUP_HEADER_HOST); if (req_host && strchr (req_host, '/')) { diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c -index d71a2cf..1a6be25 100644 +index d71a2cf..c668899 100644 --- a/libsoup/soup-message-headers.c +++ b/libsoup/soup-message-headers.c @@ -155,19 +155,8 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, @@ -62,7 +58,7 @@ index d71a2cf..1a6be25 100644 break; case SOUP_HEADER_CONTENT_TYPE: g_clear_pointer (&hdrs->content_type, g_free); -@@ -193,21 +182,7 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, +@@ -193,21 +182,6 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, } else hdrs->expectations = 0; break; @@ -81,11 +77,10 @@ index d71a2cf..1a6be25 100644 - } else - hdrs->encoding = -1; - break; -+ /* SOUP_HEADER_TRANSFER_ENCODING handled by recomputing encoding lazily */ default: break; } -@@ -951,30 +926,49 @@ soup_message_headers_foreach (SoupMessageHeaders *hdrs, +@@ -951,30 +925,50 @@ soup_message_headers_foreach (SoupMessageHeaders *hdrs, SoupEncoding soup_message_headers_get_encoding (SoupMessageHeaders *hdrs) { @@ -104,8 +99,7 @@ index d71a2cf..1a6be25 100644 - soup_message_headers_set (hdrs, SOUP_HEADER_CONTENT_LENGTH, header); - if (hdrs->encoding != -1) - return hdrs->encoding; -- } -+ /* Transfer-Encoding is checked first because it overrides the Content-Length */ ++ /* Transfer-Encoding is checked first because it overrides the Content-Length */ + transfer_encoding = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_TRANSFER_ENCODING); + if (transfer_encoding) { + /* "identity" is a wrong value according to RFC errata 408, @@ -113,8 +107,8 @@ index d71a2cf..1a6be25 100644 + * Nevertheless, the obsolete RFC 2616 stated "identity" + * as valid, so we can't handle it as unrecognized here + * for compatibility reasons. -+ */ -+ if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) ++ */ ++ if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) + hdrs->encoding = SOUP_ENCODING_CHUNKED; + else if (g_ascii_strcasecmp (transfer_encoding, "identity") != 0) + hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; @@ -122,6 +116,26 @@ index d71a2cf..1a6be25 100644 + content_length = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_CONTENT_LENGTH); + if (content_length) { + char *end; ++ ++ hdrs->content_length = g_ascii_strtoull (content_length, &end, 10); ++ if (*end) ++ hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; ++ else ++ hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; ++ } ++ } ++ ++ if (hdrs->encoding == -1) { ++ /* Per RFC 2616 4.4, a response body that doesn't indicate its ++ * encoding otherwise is terminated by connection close, and a ++ * request that doesn't indicate otherwise has no body. Note ++ * that SoupMessage calls soup_message_headers_set_encoding() ++ * to override the response body default for our own ++ * server-side messages. ++ */ ++ hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? ++ SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; + } - /* Per RFC 2616 4.4, a response body that doesn't indicate its - * encoding otherwise is terminated by connection close, and a @@ -132,28 +146,24 @@ index d71a2cf..1a6be25 100644 - */ - hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? - SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; -+ hdrs->content_length = g_ascii_strtoull (content_length, &end, 10); -+ if (*end) -+ hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; -+ else -+ hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; -+ } -+ } -+ -+ if (hdrs->encoding == -1) { -+ /* Per RFC 2616 4.4, a response body that doesn't indicate its -+ * encoding otherwise is terminated by connection close, and a -+ * request that doesn't indicate otherwise has no body. Note -+ * that SoupMessage calls soup_message_headers_set_encoding() -+ * to override the response body default for our own -+ * server-side messages. -+ */ -+ hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? -+ SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; -+ } return hdrs->encoding; } +diff --git a/tests/server-test.c b/tests/server-test.c +index b8f09d3..292dcef 100644 +--- a/tests/server-test.c ++++ b/tests/server-test.c +@@ -1317,7 +1317,9 @@ do_chunked_test (ServerData *sd, gconstpointer test_data) + const char *description; + const char *test; + } tests[] = { +- { "Lone LF", "Transfer-Encoding: chunked\r\n\r\n5;ext\n data\r\n0\r\n\r\n" }, ++ { "Single LF", "Transfer-Encoding: chunked\r\n\r\n5;ext\n data\r\n0\r\n\r\n" }, ++ { "Content-Length and Transfer-Encoding", "Content-Length: 4\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n" }, ++ { "Content-Length and Transfer-Encoding with keep alive connection", "Content-Length: 4\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\n\r\n0\r\n\r\n" }, + }; + + sd->server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); -- 2.45.4 From 9a40d1b15bd01a6eeb6b8dae8b052478e9c98db3 Mon Sep 17 00:00:00 2001 From: jykanase Date: Mon, 13 Apr 2026 11:40:01 +0000 Subject: [PATCH 5/5] enable ptests, modified existing patches and fix ssl-test --- SPECS/libsoup/CVE-2025-2784.patch | 15 ++-- SPECS/libsoup/CVE-2025-32050.patch | 6 +- SPECS/libsoup/CVE-2025-32051.patch | 8 +- SPECS/libsoup/CVE-2025-32052.patch | 6 +- SPECS/libsoup/CVE-2025-32053.patch | 8 +- SPECS/libsoup/CVE-2025-32907.patch | 113 +++++++++-------------------- SPECS/libsoup/CVE-2025-32909.patch | 6 +- SPECS/libsoup/CVE-2025-4476.patch | 6 +- SPECS/libsoup/CVE-2025-46420.patch | 10 +-- SPECS/libsoup/CVE-2026-1536.patch | 110 +++++++++++++++------------- SPECS/libsoup/CVE-2026-1760.patch | 69 +++++++++++------- SPECS/libsoup/fix-ssl-test.patch | 88 ++++++++++++++++++++++ SPECS/libsoup/libsoup.spec | 15 +++- 13 files changed, 273 insertions(+), 187 deletions(-) create mode 100644 SPECS/libsoup/fix-ssl-test.patch diff --git a/SPECS/libsoup/CVE-2025-2784.patch b/SPECS/libsoup/CVE-2025-2784.patch index e9d14536c38..f0d88e61887 100644 --- a/SPECS/libsoup/CVE-2025-2784.patch +++ b/SPECS/libsoup/CVE-2025-2784.patch @@ -10,12 +10,12 @@ https://gitlab.gnome.org/GNOME/libsoup/-/commit/c415ad0b6771992e66c70edf373566c6 .../content-sniffer/soup-content-sniffer.c | 10 +-- libsoup/soup-session.c | 6 ++ tests/auth-test.c | 76 +++++++++++++++++++ - tests/meson.build | 3 + + tests/meson.build | 4 +- tests/sniffing-test.c | 48 ++++++++++++ - 5 files changed, 138 insertions(+), 5 deletions(-) + 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c -index f6629ad..3c072c1 100644 +index 243d52e..4b4bbb0 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.c +++ b/libsoup/content-sniffer/soup-content-sniffer.c @@ -630,8 +630,11 @@ sniff_text_or_binary (SoupContentSniffer *sniffer, GBytes *buffer) @@ -162,13 +162,14 @@ index 5dbc319..51431f2 100644 main (int argc, char **argv) { diff --git a/tests/meson.build b/tests/meson.build -index fc1cb3f..ff94a4f 100644 +index fc1cb3f..946395d 100644 --- a/tests/meson.build +++ b/tests/meson.build -@@ -91,6 +91,9 @@ tests = [ +@@ -90,7 +90,9 @@ tests = [ + {'name': 'session'}, {'name': 'server-auth'}, {'name': 'server'}, - {'name': 'sniffing'}, +- {'name': 'sniffing'}, + {'name': 'sniffing', + 'depends': [test_resources], + }, @@ -242,5 +243,5 @@ index 6116719..7857732 100644 g_uri_unref (base_uri); -- -2.45.3 +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32050.patch b/SPECS/libsoup/CVE-2025-32050.patch index ae910906bc4..92b1d04af40 100644 --- a/SPECS/libsoup/CVE-2025-32050.patch +++ b/SPECS/libsoup/CVE-2025-32050.patch @@ -10,10 +10,10 @@ https://gitlab.gnome.org/GNOME/libsoup/-/commit/9bb0a55de55c6940ced811a64fbca82f 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c -index 8382b8f..4468415 100644 +index 13fe683..40df826 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c -@@ -907,7 +907,7 @@ append_param_quoted (GString *string, +@@ -912,7 +912,7 @@ append_param_quoted (GString *string, const char *name, const char *value) { @@ -23,5 +23,5 @@ index 8382b8f..4468415 100644 g_string_append (string, name); g_string_append (string, "=\""); -- -2.45.3 +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32051.patch b/SPECS/libsoup/CVE-2025-32051.patch index 928699b9f1f..b33d10ce992 100644 --- a/SPECS/libsoup/CVE-2025-32051.patch +++ b/SPECS/libsoup/CVE-2025-32051.patch @@ -12,10 +12,10 @@ https://gitlab.gnome.org/GNOME/libsoup/-/commit/0713ba4a719da938dc8facc89fca99cd 1 file changed, 11 insertions(+) diff --git a/libsoup/soup-uri-utils.c b/libsoup/soup-uri-utils.c -index be2b79b..ad70fe6 100644 +index 8fea9a6..ce9b2a1 100644 --- a/libsoup/soup-uri-utils.c +++ b/libsoup/soup-uri-utils.c -@@ -286,6 +286,7 @@ soup_uri_decode_data_uri (const char *uri, +@@ -294,6 +294,7 @@ soup_uri_decode_data_uri (const char *uri, gboolean base64 = FALSE; char *uri_string; GBytes *bytes; @@ -23,7 +23,7 @@ index be2b79b..ad70fe6 100644 g_return_val_if_fail (uri != NULL, NULL); -@@ -300,9 +301,19 @@ soup_uri_decode_data_uri (const char *uri, +@@ -308,9 +309,19 @@ soup_uri_decode_data_uri (const char *uri, if (content_type) *content_type = NULL; @@ -44,5 +44,5 @@ index be2b79b..ad70fe6 100644 start = uri_string + 5; comma = strchr (start, ','); -- -2.45.3 +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32052.patch b/SPECS/libsoup/CVE-2025-32052.patch index 41ea4720590..bd47b5c3cfc 100644 --- a/SPECS/libsoup/CVE-2025-32052.patch +++ b/SPECS/libsoup/CVE-2025-32052.patch @@ -12,10 +12,10 @@ https://gitlab.gnome.org/GNOME/libsoup/-/commit/f182429e5b1fc034050510da20c93256 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c -index 150d285..a772c7c 100644 +index 4b4bbb0..3c072c1 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.c +++ b/libsoup/content-sniffer/soup-content-sniffer.c -@@ -529,7 +529,7 @@ sniff_unknown (SoupContentSniffer *sniffer, GBytes *buffer, +@@ -521,7 +521,7 @@ sniff_unknown (SoupContentSniffer *sniffer, GBytes *buffer, guint index_pattern = 0; gboolean skip_row = FALSE; @@ -25,5 +25,5 @@ index 150d285..a772c7c 100644 /* Skip insignificant white space ("WS" in the spec) */ if (type_row->pattern[index_pattern] == ' ') { -- -2.45.3 +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32053.patch b/SPECS/libsoup/CVE-2025-32053.patch index 5a49b386f2e..f070409cc2f 100644 --- a/SPECS/libsoup/CVE-2025-32053.patch +++ b/SPECS/libsoup/CVE-2025-32053.patch @@ -10,10 +10,10 @@ Upstream patch reference: https://gitlab.gnome.org/GNOME/libsoup/-/commit/eaed42 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c -index b62e4888..5a181ff1 100644 +index 3c072c1..55e5754 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.c +++ b/libsoup/content-sniffer/soup-content-sniffer.c -@@ -641,7 +641,7 @@ skip_insignificant_space (const char *resource, int *pos, int resource_length) +@@ -641,7 +641,7 @@ skip_insignificant_space (const char *resource, gsize *pos, gsize resource_lengt (resource[*pos] == '\x0D')) { *pos = *pos + 1; @@ -22,7 +22,7 @@ index b62e4888..5a181ff1 100644 return TRUE; } -@@ -704,7 +704,7 @@ sniff_feed_or_html (SoupContentSniffer *sniffer, GBytes *buffer) +@@ -701,7 +701,7 @@ sniff_feed_or_html (SoupContentSniffer *sniffer, GBytes *buffer) do { pos++; @@ -32,5 +32,5 @@ index b62e4888..5a181ff1 100644 } while (resource[pos] != '>'); -- -GitLab +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32907.patch b/SPECS/libsoup/CVE-2025-32907.patch index ae9a3bc520d..fc1cf99b2f3 100644 --- a/SPECS/libsoup/CVE-2025-32907.patch +++ b/SPECS/libsoup/CVE-2025-32907.patch @@ -10,11 +10,13 @@ Closes #428 Part-of: Upstream Patch Reference: https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/452/diffs?commit_id=9bb92f7a685e31e10e9e8221d0342280432ce836 +https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/452/diffs?commit_id=eeace39ec686094ff6a05a43e5fce06e9c37f376 --- libsoup/soup-message-headers.c | 1 + + meson.build | 4 + tests/meson.build | 1 + - tests/server-mem-limit-test.c | 144 +++++++++++++++++++++++++++++++++ - 3 files changed, 146 insertions(+) + tests/server-mem-limit-test.c | 149 +++++++++++++++++++++++++++++++++ + 4 files changed, 155 insertions(+) create mode 100644 tests/server-mem-limit-test.c diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c @@ -29,8 +31,23 @@ index c5168ea..9123dc1 100644 } } } +diff --git a/meson.build b/meson.build +index ff5dc95..5ed4125 100644 +--- a/meson.build ++++ b/meson.build +@@ -389,6 +389,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/meson.build b/tests/meson.build -index ff94a4f..d78df11 100644 +index 946395d..bf85f2b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -89,6 +89,7 @@ tests = [ @@ -39,14 +56,14 @@ index ff94a4f..d78df11 100644 {'name': 'server-auth'}, + {'name': 'server-mem-limit'}, {'name': 'server'}, - {'name': 'sniffing'}, {'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 0000000..98f1c40 +index 0000000..65dc875 --- /dev/null +++ b/tests/server-mem-limit-test.c -@@ -0,0 +1,144 @@ +@@ -0,0 +1,149 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2025 Red Hat @@ -145,9 +162,9 @@ index 0000000..98f1c40 + return; + #endif + -+ range = g_string_sized_new (99 * 1024); ++ range = g_string_sized_new (60 * 1024); + g_string_append (range, "bytes=1024"); -+ while (range->len < 99 * 1024) ++ while (range->len < 60 * 1024) + g_string_append (range, chunk); + + session = soup_test_session_new (NULL); @@ -175,14 +192,19 @@ index 0000000..98f1c40 +{ + 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); + @@ -192,70 +214,5 @@ index 0000000..98f1c40 + return ret; +} -- -2.34.1 - - -From abedf4259b478b2ad5c33af36fb163b5ace821c0 Mon Sep 17 00:00:00 2001 -From: Kevin Lockwood -Date: Fri, 13 Jun 2025 09:57:54 -0700 -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: -Upstream Patch Reference: https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/452/diffs?commit_id=eeace39ec686094ff6a05a43e5fce06e9c37f376 ---- - 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 ff5dc95..5ed4125 100644 ---- a/meson.build -+++ b/meson.build -@@ -389,6 +389,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 98f1c40..65dc875 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); - --- -2.34.1 +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-32909.patch b/SPECS/libsoup/CVE-2025-32909.patch index c593b04d15f..6daa62c44a0 100644 --- a/SPECS/libsoup/CVE-2025-32909.patch +++ b/SPECS/libsoup/CVE-2025-32909.patch @@ -10,10 +10,10 @@ Link: https://gitlab.gnome.org/GNOME/libsoup/-/commit/ba4c3a6f988beff59e45801ab3 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libsoup/content-sniffer/soup-content-sniffer.c b/libsoup/content-sniffer/soup-content-sniffer.c -index 5a181ff1..aeee2e25 100644 +index 55e5754..3d0e831 100644 --- a/libsoup/content-sniffer/soup-content-sniffer.c +++ b/libsoup/content-sniffer/soup-content-sniffer.c -@@ -243,9 +243,14 @@ sniff_mp4 (SoupContentSniffer *sniffer, GBytes *buffer) +@@ -240,9 +240,14 @@ sniff_mp4 (SoupContentSniffer *sniffer, GBytes *buffer) gsize resource_length; const char *resource = g_bytes_get_data (buffer, &resource_length); resource_length = MIN (512, resource_length); @@ -30,5 +30,5 @@ index 5a181ff1..aeee2e25 100644 box_size = ((box_size >> 24) | ((box_size << 8) & 0x00FF0000) | -- -GitLab +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-4476.patch b/SPECS/libsoup/CVE-2025-4476.patch index 7aaaa2b74a0..ebdd4653e17 100644 --- a/SPECS/libsoup/CVE-2025-4476.patch +++ b/SPECS/libsoup/CVE-2025-4476.patch @@ -16,10 +16,10 @@ Fixes #440 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsoup/auth/soup-auth-digest.c b/libsoup/auth/soup-auth-digest.c -index d8bb2910..292f2045 100644 +index 1742903..d3a0ab3 100644 --- a/libsoup/auth/soup-auth-digest.c +++ b/libsoup/auth/soup-auth-digest.c -@@ -220,7 +220,7 @@ soup_auth_digest_get_protection_space (SoupAuth *auth, GUri *source_uri) +@@ -235,7 +235,7 @@ soup_auth_digest_get_protection_space (SoupAuth *auth, GUri *source_uri) if (uri && g_strcmp0 (g_uri_get_scheme (uri), g_uri_get_scheme (source_uri)) == 0 && g_uri_get_port (uri) == g_uri_get_port (source_uri) && @@ -29,5 +29,5 @@ index d8bb2910..292f2045 100644 else dir = NULL; -- -GitLab +2.45.4 diff --git a/SPECS/libsoup/CVE-2025-46420.patch b/SPECS/libsoup/CVE-2025-46420.patch index 86f03f0b092..16bd304cc57 100644 --- a/SPECS/libsoup/CVE-2025-46420.patch +++ b/SPECS/libsoup/CVE-2025-46420.patch @@ -12,10 +12,10 @@ https://gitlab.gnome.org/GNOME/libsoup/-/commit/c9083869ec2a3037e6df4bd86b45c419 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c -index 4468415..d28ddff 100644 +index 40df826..99ff5e9 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c -@@ -530,7 +530,7 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) +@@ -538,7 +538,7 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) GSList *unsorted; QualityItem *array; GSList *sorted, *iter; @@ -24,7 +24,7 @@ index 4468415..d28ddff 100644 const char *param, *equal, *value; double qval; int n; -@@ -543,9 +543,8 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) +@@ -551,9 +551,8 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) unsorted = soup_header_parse_list (header); array = g_new0 (QualityItem, g_slist_length (unsorted)); for (iter = unsorted, n = 0; iter; iter = iter->next) { @@ -35,7 +35,7 @@ index 4468415..d28ddff 100644 param = skip_lws (semi + 1); if (*param != 'q') continue; -@@ -577,15 +576,15 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) +@@ -585,15 +584,15 @@ soup_header_parse_quality_list (const char *header, GSList **unacceptable) if (qval == 0.0) { if (unacceptable) { *unacceptable = g_slist_prepend (*unacceptable, @@ -55,5 +55,5 @@ index 4468415..d28ddff 100644 qsort (array, n, sizeof (QualityItem), sort_by_qval); sorted = NULL; -- -2.45.3 +2.45.4 diff --git a/SPECS/libsoup/CVE-2026-1536.patch b/SPECS/libsoup/CVE-2026-1536.patch index a33421db2f4..8ef7d315174 100644 --- a/SPECS/libsoup/CVE-2026-1536.patch +++ b/SPECS/libsoup/CVE-2026-1536.patch @@ -29,8 +29,8 @@ Upstream Patch Reference: https://gitlab.gnome.org/GNOME/libsoup/-/merge_request libsoup/soup-multipart.c | 4 +- libsoup/soup-session.c | 4 +- libsoup/websocket/soup-websocket.c | 28 +- - tests/header-parsing-test.c | 257 +++++++++++++----- - 19 files changed, 315 insertions(+), 158 deletions(-) + tests/header-parsing-test.c | 263 +++++++++++++----- + 19 files changed, 320 insertions(+), 159 deletions(-) diff --git a/libsoup/auth/soup-auth-manager.c b/libsoup/auth/soup-auth-manager.c index 47ce2a2..4080866 100644 @@ -150,7 +150,7 @@ index e68884f..a31a83d 100644 g_free (challenge); } diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c -index d1af115..960e8c6 100644 +index d1af115..7e9cc45 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c @@ -251,7 +251,7 @@ handle_partial_get (SoupServerMessage *msg) @@ -488,10 +488,10 @@ index 9123dc1..d71a2cf 100644 } diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c -index 292e4e5..5eb19aa 100644 +index 2f5b267..aa20c0c 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c -@@ -1103,7 +1103,7 @@ soup_message_set_request_body (SoupMessage *msg, +@@ -1102,7 +1102,7 @@ soup_message_set_request_body (SoupMessage *msg, g_warn_if_fail (strchr (content_type, '/') != NULL); if (soup_message_headers_get_content_type (priv->request_headers, NULL) != content_type) @@ -500,7 +500,7 @@ index 292e4e5..5eb19aa 100644 } if (content_length == -1) -@@ -3111,12 +3111,12 @@ soup_message_set_request_host_from_uri (SoupMessage *msg, +@@ -3110,12 +3110,12 @@ soup_message_set_request_host_from_uri (SoupMessage *msg, host = soup_uri_get_host_for_headers (uri); if (soup_uri_uses_default_port (uri)) @@ -515,7 +515,7 @@ index 292e4e5..5eb19aa 100644 g_free (value); } g_free (host); -@@ -3152,7 +3152,7 @@ soup_message_force_keep_alive_if_needed (SoupMessage *msg) +@@ -3151,7 +3151,7 @@ soup_message_force_keep_alive_if_needed (SoupMessage *msg) if (!soup_message_headers_header_contains_common (priv->request_headers, SOUP_HEADER_CONNECTION, "Keep-Alive") && !soup_message_headers_header_contains_common (priv->request_headers, SOUP_HEADER_CONNECTION, "close") && !soup_message_headers_header_contains_common (priv->request_headers, SOUP_HEADER_CONNECTION, "Upgrade")) { @@ -659,10 +659,21 @@ index bdcbd7c..e5b4565 100644 soup_message_headers_remove_common (response_headers, SOUP_HEADER_SEC_WEBSOCKET_EXTENSIONS); diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c -index a81a69b..11e1920 100644 +index a81a69b..5509258 100644 --- a/tests/header-parsing-test.c +++ b/tests/header-parsing-test.c -@@ -15,6 +15,7 @@ static struct RequestTest { +@@ -6,6 +6,10 @@ typedef struct { + const char *name, *value; + } Header; + ++static char only_newlines[] = { ++ '\n', '\n', '\n', '\n' ++}; ++ + static struct RequestTest { + const char *description; + const char *bugref; +@@ -15,6 +19,7 @@ static struct RequestTest { const char *method, *path; SoupHTTPVersion version; Header headers[10]; @@ -670,7 +681,7 @@ index a81a69b..11e1920 100644 } reqtests[] = { /**********************/ /*** VALID REQUESTS ***/ -@@ -24,7 +25,7 @@ static struct RequestTest { +@@ -24,7 +29,7 @@ static struct RequestTest { "GET / HTTP/1.0\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_0, @@ -679,7 +690,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header", NULL, -@@ -33,7 +34,7 @@ static struct RequestTest { +@@ -33,7 +38,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -688,7 +699,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header, no leading whitespace", NULL, -@@ -42,7 +43,7 @@ static struct RequestTest { +@@ -42,7 +47,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -697,7 +708,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header including trailing whitespace", NULL, -@@ -51,7 +52,7 @@ static struct RequestTest { +@@ -51,7 +56,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -706,7 +717,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header, wrapped", NULL, -@@ -60,7 +61,7 @@ static struct RequestTest { +@@ -60,7 +65,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Foo", "bar baz" }, { NULL } @@ -715,7 +726,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header, wrapped with additional whitespace", NULL, -@@ -69,7 +70,7 @@ static struct RequestTest { +@@ -69,7 +74,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Foo", "bar baz" }, { NULL } @@ -724,7 +735,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header, wrapped with tab", NULL, -@@ -78,7 +79,7 @@ static struct RequestTest { +@@ -78,7 +83,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Foo", "bar baz" }, { NULL } @@ -733,7 +744,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header, wrapped before value", NULL, -@@ -87,7 +88,7 @@ static struct RequestTest { +@@ -87,7 +92,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Foo", "bar baz" }, { NULL } @@ -742,7 +753,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 1 header with empty value", NULL, -@@ -96,7 +97,7 @@ static struct RequestTest { +@@ -96,7 +101,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "" }, { NULL } @@ -751,7 +762,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 2 headers", NULL, -@@ -106,7 +107,7 @@ static struct RequestTest { +@@ -106,7 +111,7 @@ static struct RequestTest { { { "Host", "example.com" }, { "Connection", "close" }, { NULL } @@ -760,7 +771,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 3 headers", NULL, -@@ -117,7 +118,7 @@ static struct RequestTest { +@@ -117,7 +122,7 @@ static struct RequestTest { { "Connection", "close" }, { "Blah", "blah" }, { NULL } @@ -769,7 +780,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 3 headers, 1st wrapped", NULL, -@@ -128,7 +129,7 @@ static struct RequestTest { +@@ -128,7 +133,7 @@ static struct RequestTest { { "Foo", "bar baz" }, { "Blah", "blah" }, { NULL } @@ -778,7 +789,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 3 headers, 2nd wrapped", NULL, -@@ -139,7 +140,7 @@ static struct RequestTest { +@@ -139,7 +144,7 @@ static struct RequestTest { { "Blah", "blah" }, { "Foo", "bar baz" }, { NULL } @@ -787,7 +798,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ 3 headers, 3rd wrapped", NULL, -@@ -150,7 +151,7 @@ static struct RequestTest { +@@ -150,7 +155,7 @@ static struct RequestTest { { "Blah", "blah" }, { "Foo", "bar baz" }, { NULL } @@ -796,7 +807,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ same header multiple times", NULL, -@@ -159,7 +160,7 @@ static struct RequestTest { +@@ -159,7 +164,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Foo", "bar, baz, quux" }, { NULL } @@ -805,7 +816,7 @@ index a81a69b..11e1920 100644 }, { "Connection header on HTTP/1.0 message", NULL, -@@ -169,21 +170,21 @@ static struct RequestTest { +@@ -169,21 +174,21 @@ static struct RequestTest { { { "Connection", "Bar, Quux" }, { "Foo", "bar" }, { NULL } @@ -830,7 +841,7 @@ index a81a69b..11e1920 100644 }, /* It's better for this to be passed through: this means a SoupServer -@@ -193,7 +194,7 @@ static struct RequestTest { +@@ -193,7 +198,7 @@ static struct RequestTest { "GET AbOuT: HTTP/1.1\r\n", -1, SOUP_STATUS_OK, "GET", "AbOuT:", SOUP_HTTP_1_1, @@ -839,7 +850,7 @@ index a81a69b..11e1920 100644 }, /****************************/ -@@ -208,7 +209,7 @@ static struct RequestTest { +@@ -208,7 +213,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -848,7 +859,7 @@ index a81a69b..11e1920 100644 }, /* RFC 2616 section 3.1 says we MUST accept this */ -@@ -219,7 +220,7 @@ static struct RequestTest { +@@ -219,7 +224,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -857,7 +868,7 @@ index a81a69b..11e1920 100644 }, /* RFC 2616 section 19.3 says we SHOULD accept these */ -@@ -231,7 +232,7 @@ static struct RequestTest { +@@ -231,7 +236,7 @@ static struct RequestTest { { { "Host", "example.com" }, { "Connection", "close" }, { NULL } @@ -866,7 +877,7 @@ index a81a69b..11e1920 100644 }, { "LF instead of CRLF after Request-Line", NULL, -@@ -240,7 +241,7 @@ static struct RequestTest { +@@ -240,7 +245,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -875,7 +886,7 @@ index a81a69b..11e1920 100644 }, { "Mixed CRLF/LF", "666316", -@@ -252,7 +253,7 @@ static struct RequestTest { +@@ -252,7 +257,7 @@ static struct RequestTest { { "e", "f" }, { "g", "h" }, { NULL } @@ -884,7 +895,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ incorrect whitespace in Request-Line", NULL, -@@ -261,7 +262,7 @@ static struct RequestTest { +@@ -261,7 +266,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -893,7 +904,7 @@ index a81a69b..11e1920 100644 }, { "Req w/ incorrect whitespace after Request-Line", "475169", -@@ -270,7 +271,7 @@ static struct RequestTest { +@@ -270,7 +275,7 @@ static struct RequestTest { "GET", "/", SOUP_HTTP_1_1, { { "Host", "example.com" }, { NULL } @@ -902,7 +913,7 @@ index a81a69b..11e1920 100644 }, /* If the request/status line is parseable, then we -@@ -284,7 +285,7 @@ static struct RequestTest { +@@ -284,7 +289,7 @@ static struct RequestTest { { { "Host", "example.com" }, { "Bar", "two" }, { NULL } @@ -911,7 +922,7 @@ index a81a69b..11e1920 100644 }, { "First header line is continuation", "666316", -@@ -294,7 +295,7 @@ static struct RequestTest { +@@ -294,7 +299,7 @@ static struct RequestTest { { { "Host", "example.com" }, { "c", "d" }, { NULL } @@ -920,7 +931,7 @@ index a81a69b..11e1920 100644 }, { "Zero-length header name", "666316", -@@ -304,7 +305,7 @@ static struct RequestTest { +@@ -304,7 +309,7 @@ static struct RequestTest { { { "a", "b" }, { "c", "d" }, { NULL } @@ -929,7 +940,7 @@ index a81a69b..11e1920 100644 }, { "CR in header name", "666316", -@@ -314,7 +315,7 @@ static struct RequestTest { +@@ -314,7 +319,7 @@ static struct RequestTest { { { "a", "b" }, { "c", "d" }, { NULL } @@ -938,7 +949,7 @@ index a81a69b..11e1920 100644 }, { "CR in header value", "666316", -@@ -327,7 +328,7 @@ static struct RequestTest { +@@ -327,7 +332,7 @@ static struct RequestTest { { "s", "t" }, /* CR at end is ignored */ { "c", "d" }, { NULL } @@ -947,7 +958,7 @@ index a81a69b..11e1920 100644 }, { "Tab in header name", "666316", -@@ -342,7 +343,7 @@ static struct RequestTest { +@@ -342,7 +347,7 @@ static struct RequestTest { { "p", "q z: w" }, { "c", "d" }, { NULL } @@ -956,7 +967,7 @@ index a81a69b..11e1920 100644 }, { "Tab in header value", "666316", -@@ -355,7 +356,7 @@ static struct RequestTest { +@@ -355,7 +360,7 @@ static struct RequestTest { { "z", "w" }, /* trailing tab ignored */ { "c", "d" }, { NULL } @@ -965,7 +976,7 @@ index a81a69b..11e1920 100644 }, /************************/ -@@ -366,70 +367,70 @@ static struct RequestTest { +@@ -366,70 +371,70 @@ static struct RequestTest { "GET /\r\n", -1, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, @@ -1046,7 +1057,7 @@ index a81a69b..11e1920 100644 }, // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377 -@@ -437,15 +438,42 @@ static struct RequestTest { +@@ -437,15 +442,42 @@ static struct RequestTest { "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, @@ -1059,8 +1070,9 @@ index a81a69b..11e1920 100644 SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, - { { NULL } } +- } + { { NULL } }, 0 - } ++ }, + + { "Only newlines", NULL, + only_newlines, sizeof (only_newlines), @@ -1091,7 +1103,7 @@ index a81a69b..11e1920 100644 }; static const int num_reqtests = G_N_ELEMENTS (reqtests); -@@ -892,10 +920,17 @@ do_request_tests (void) +@@ -892,10 +924,17 @@ do_request_tests (void) len = strlen (reqtests[i].request); else len = reqtests[i].length; @@ -1109,7 +1121,7 @@ index a81a69b..11e1920 100644 if (SOUP_STATUS_IS_SUCCESSFUL (status)) { g_assert_cmpstr (method, ==, reqtests[i].method); g_assert_cmpstr (path, ==, reqtests[i].path); -@@ -1243,16 +1278,21 @@ do_append_param_tests (void) +@@ -1243,16 +1282,21 @@ do_append_param_tests (void) static const struct { const char *description, *name, *value; @@ -1141,7 +1153,7 @@ index a81a69b..11e1920 100644 }; static void -@@ -1262,15 +1302,105 @@ do_bad_header_tests (void) +@@ -1262,15 +1306,105 @@ do_bad_header_tests (void) int i; hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); @@ -1174,7 +1186,7 @@ index a81a69b..11e1920 100644 + soup_message_headers_append (hdrs, bad_header_values[i].name, + bad_header_values[i].value); + g_test_assert_expected_messages (); - } ++ } + + /* soup_message_headers_replace: bad values */ + for (i = 0; i < G_N_ELEMENTS (bad_header_values); i++) { @@ -1185,7 +1197,7 @@ index a81a69b..11e1920 100644 + soup_message_headers_replace (hdrs, bad_header_values[i].name, + bad_header_values[i].value); + g_test_assert_expected_messages (); -+ } + } + + /* soup_message_headers_set_content_type: bad values */ + for (i = 0; i < G_N_ELEMENTS (bad_header_values); i++) { @@ -1255,7 +1267,7 @@ index a81a69b..11e1920 100644 soup_message_headers_unref (hdrs); } -@@ -1289,6 +1419,7 @@ main (int argc, char **argv) +@@ -1289,6 +1423,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); diff --git a/SPECS/libsoup/CVE-2026-1760.patch b/SPECS/libsoup/CVE-2026-1760.patch index dea10bcc7e1..2dcd2492c9b 100644 --- a/SPECS/libsoup/CVE-2026-1760.patch +++ b/SPECS/libsoup/CVE-2026-1760.patch @@ -8,32 +8,49 @@ Closes #475 Upstream Patch Reference: https://gitlab.gnome.org/GNOME/libsoup/-/commit/30b682af333402eeef4fad3acbc865771f85281a.patch --- - libsoup/server/soup-server-io.c | 8 +++ - libsoup/soup-message-headers.c | 86 +++++++++++++++------------------ - tests/server-test.c | 4 +- - 3 files changed, 51 insertions(+), 47 deletions(-) + libsoup/server/soup-server-io.c | 8 +++ + libsoup/soup-message-headers-private.h | 5 ++ + libsoup/soup-message-headers.c | 89 ++++++++++++-------------- + tests/server-test.c | 4 +- + 4 files changed, 58 insertions(+), 48 deletions(-) diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c -index 7e9cc45..9e237a3 100644 +index 7e9cc45..c90fc47 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c @@ -599,6 +599,14 @@ parse_headers (SoupServerMessage *msg, return SOUP_STATUS_BAD_REQUEST; } -+ /* A server MAY reject a request that contains both Content-Length and ++ /* A server MAY reject a request that contains both Content-Length and + * Transfer-Encoding or process such a request in accordance with the + * Transfer-Encoding alone. Regardless, the server MUST close the connection + * after responding to such a request to avoid the potential attacks + */ + if (*encoding == SOUP_ENCODING_CHUNKED && soup_message_headers_get_one_common (request_headers, SOUP_HEADER_CONTENT_LENGTH)) -+ soup_message_headers_replace_common (request_headers, SOUP_HEADER_CONNECTION, "close", TRUE); ++ soup_message_headers_replace_common (request_headers, SOUP_HEADER_CONNECTION, "close", SOUP_HEADER_VALUE_TRUSTED); + /* Generate correct context for request */ req_host = soup_message_headers_get_one_common (request_headers, SOUP_HEADER_HOST); if (req_host && strchr (req_host, '/')) { +diff --git a/libsoup/soup-message-headers-private.h b/libsoup/soup-message-headers-private.h +index 59fb206..9ef7395 100644 +--- a/libsoup/soup-message-headers-private.h ++++ b/libsoup/soup-message-headers-private.h +@@ -10,6 +10,11 @@ + + G_BEGIN_DECLS + ++typedef enum { ++ SOUP_HEADER_VALUE_UNTRUSTED, ++ SOUP_HEADER_VALUE_TRUSTED ++} SoupHeaderValueTrusted; ++ + gboolean soup_message_headers_append_untrusted_data (SoupMessageHeaders *hdrs, + const char *name, + const char *value); diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c -index d71a2cf..c668899 100644 +index d71a2cf..b6a0ec2 100644 --- a/libsoup/soup-message-headers.c +++ b/libsoup/soup-message-headers.c @@ -155,19 +155,8 @@ soup_message_headers_set (SoupMessageHeaders *hdrs, @@ -80,13 +97,13 @@ index d71a2cf..c668899 100644 default: break; } -@@ -951,30 +925,50 @@ soup_message_headers_foreach (SoupMessageHeaders *hdrs, +@@ -951,30 +925,51 @@ soup_message_headers_foreach (SoupMessageHeaders *hdrs, SoupEncoding soup_message_headers_get_encoding (SoupMessageHeaders *hdrs) { - const char *header; + const char *content_length; -+ const char *transfer_encoding; ++ const char *transfer_encoding; if (hdrs->encoding != -1) return hdrs->encoding; @@ -99,16 +116,18 @@ index d71a2cf..c668899 100644 - soup_message_headers_set (hdrs, SOUP_HEADER_CONTENT_LENGTH, header); - if (hdrs->encoding != -1) - return hdrs->encoding; +- } + /* Transfer-Encoding is checked first because it overrides the Content-Length */ + transfer_encoding = soup_message_headers_get_one_common (hdrs, SOUP_HEADER_TRANSFER_ENCODING); -+ if (transfer_encoding) { ++ ++ if (transfer_encoding) { + /* "identity" is a wrong value according to RFC errata 408, + * and RFC 7230 does not list it as valid transfer-coding. + * Nevertheless, the obsolete RFC 2616 stated "identity" + * as valid, so we can't handle it as unrecognized here + * for compatibility reasons. -+ */ -+ if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) ++ */ ++ if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) + hdrs->encoding = SOUP_ENCODING_CHUNKED; + else if (g_ascii_strcasecmp (transfer_encoding, "identity") != 0) + hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; @@ -123,19 +142,19 @@ index d71a2cf..c668899 100644 + else + hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; + } -+ } ++ } + -+ if (hdrs->encoding == -1) { -+ /* Per RFC 2616 4.4, a response body that doesn't indicate its -+ * encoding otherwise is terminated by connection close, and a -+ * request that doesn't indicate otherwise has no body. Note -+ * that SoupMessage calls soup_message_headers_set_encoding() -+ * to override the response body default for our own -+ * server-side messages. -+ */ -+ hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? -+ SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; - } ++ if (hdrs->encoding == -1) { ++ /* Per RFC 2616 4.4, a response body that doesn't indicate its ++ * encoding otherwise is terminated by connection close, and a ++ * request that doesn't indicate otherwise has no body. Note ++ * that SoupMessage calls soup_message_headers_set_encoding() ++ * to override the response body default for our own ++ * server-side messages. ++ */ ++ hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? ++ SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; ++ } - /* Per RFC 2616 4.4, a response body that doesn't indicate its - * encoding otherwise is terminated by connection close, and a diff --git a/SPECS/libsoup/fix-ssl-test.patch b/SPECS/libsoup/fix-ssl-test.patch new file mode 100644 index 00000000000..ac00ac0f49a --- /dev/null +++ b/SPECS/libsoup/fix-ssl-test.patch @@ -0,0 +1,88 @@ +From f74f956ed1e09767d605c68baaf6615f63e41205 Mon Sep 17 00:00:00 2001 +From: Patrick Griffis +Date: Mon, 13 Jan 2025 12:22:02 -0600 +Subject: [PATCH] ssl-test: Respect pkcs11_tests build option + +Closes #304 + +Upstream Patch reference: https://gitlab.gnome.org/GNOME/libsoup/-/commit/f74f956ed1e09767d605c68baaf6615f63e41205.patch +--- + tests/meson.build | 16 ++++++++++++++-- + tests/ssl-test.c | 6 +++--- + 2 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/tests/meson.build b/tests/meson.build +index bf85f2b..23fdf98 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -5,6 +5,15 @@ installed_tests_enabled = get_option('installed_tests') + installed_tests_template_tap = files('template-tap.test.in') + abs_installed_tests_execdir = join_paths(prefix, installed_tests_execdir) + ++if get_option('pkcs11_tests').enabled() ++ assert(gnutls_dep.found()) # Required earlier. ++ enable_pkcs11_tests = true ++elif get_option('pkcs11_tests').auto() ++ enable_pkcs11_tests = gnutls_dep.found() ++else ++ enable_pkcs11_tests = false ++endif ++ + if cc.get_id() == 'msvc' + test_utils = static_library(test_utils_name, test_utils_name + '.c', + dependencies : [ libsoup_static_dep, unix_socket_dep ]) +@@ -23,7 +32,7 @@ test_resources = gnome.compile_resources('soup-tests', + install_dir : installed_tests_execdir, + ) + +-if gnutls_dep.found() ++if enable_pkcs11_tests + mock_pkcs11_module = shared_module('mock-pkcs11', + sources: 'mock-pkcs11.c', + name_prefix: '', +@@ -98,7 +107,10 @@ tests = [ + {'name': 'ssl', + 'dependencies': [gnutls_dep], + 'depends': mock_pkcs11_module, +- 'c_args': '-DHAVE_GNUTLS=@0@'.format(gnutls_dep.found() ? 1 : 0), ++ 'c_args': [ ++ '-DHAVE_GNUTLS=@0@'.format(gnutls_dep.found() ? 1 : 0), ++ '-DENABLE_PKCS11_TESTS=@0@'.format(enable_pkcs11_tests ? 1 : 0), ++ ] + }, + {'name': 'streaming'}, + {'name': 'timeout'}, +diff --git a/tests/ssl-test.c b/tests/ssl-test.c +index 12f81af..7ebc17e 100644 +--- a/tests/ssl-test.c ++++ b/tests/ssl-test.c +@@ -450,7 +450,7 @@ do_tls_interaction_msg_test (gconstpointer data) + g_object_unref (msg); + + /* Currently on the gnutls backend supports pkcs#11 */ +- if (g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (g_tls_backend_get_default ())), "GTlsBackendGnutls") == 0) { ++ if (ENABLE_PKCS11_TESTS && g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (g_tls_backend_get_default ())), "GTlsBackendGnutls") == 0) { + g_test_message ("Running PKCS#11 tests"); + + /* Using PKCS#11 works, and asks for a PIN */ +@@ -646,7 +646,7 @@ do_tls_interaction_preconnect_test (gconstpointer data) + soup_session_abort (session); + + /* Currently on the gnutls backend supports pkcs#11 */ +- if (g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (g_tls_backend_get_default ())), "GTlsBackendGnutls") == 0) { ++ if (ENABLE_PKCS11_TESTS && g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (g_tls_backend_get_default ())), "GTlsBackendGnutls") == 0) { + GTlsCertificate *pkcs11_certificate; + + pkcs11_certificate = g_tls_certificate_new_from_pkcs11_uris ( +@@ -710,7 +710,7 @@ main (int argc, char **argv) + + test_init (argc, argv, NULL); + +-#if HAVE_GNUTLS ++#if HAVE_GNUTLS && ENABLE_PKCS11_TESTS + char *module_path = soup_test_build_filename_abs (G_TEST_BUILT, "mock-pkcs11.so", NULL); + g_assert_true (g_file_test (module_path, G_FILE_TEST_EXISTS)); + +-- +2.45.4 + diff --git a/SPECS/libsoup/libsoup.spec b/SPECS/libsoup/libsoup.spec index 55378cae19e..d248fd363a7 100644 --- a/SPECS/libsoup/libsoup.spec +++ b/SPECS/libsoup/libsoup.spec @@ -42,9 +42,10 @@ Patch23: CVE-2026-0716.patch Patch24: CVE-2026-1467.patch Patch25: CVE-2026-1761.patch Patch26: CVE-2026-1801.patch -Patch27: CVE-2026-1760.patch -Patch28: CVE-2026-2443.patch -Patch29: CVE-2026-2369.patch +Patch27: fix-ssl-test.patch +Patch28: CVE-2026-1760.patch +Patch29: CVE-2026-2443.patch +Patch30: CVE-2026-2369.patch BuildRequires: meson @@ -116,7 +117,13 @@ These are the additional language files of libsoup. -Dautobahn=disabled \ -Dhttp2_tests=disabled \ -Dntlm=disabled \ +%if 0%{?with_check} + -Dtests=true \ + -Dgssapi=disabled \ + -Dpkcs11_tests=disabled +%else -Dtests=false +%endif %meson_build %install @@ -159,6 +166,8 @@ find %{buildroot} -type f -name "*.la" -delete -print %changelog * Tue Feb 17 2026 Azure Linux Security Servicing Account - 3.0.4-14 - Patch for CVE-2026-1760, CVE-2026-2443, CVE-2026-2369 +- Enable ptests and fix ssl-test +- Modified existing patches * Mon Feb 16 2026 Azure Linux Security Servicing Account - 3.0.4-13 - Patch for CVE-2026-1801, CVE-2026-1761, CVE-2026-1467