Skip to content

[AutoPR- Security] Patch libsoup for CVE-2025-4948 [HIGH] #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: fasttrack/3.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions SPECS/libsoup/CVE-2025-4948.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
From 14e00acc5167fc26a2bf71e2df6a754d340152cd Mon Sep 17 00:00:00 2001
From: Milan Crha <[email protected]>
Date: Thu, 15 May 2025 17:49:11 +0200
Subject: [PATCH] soup-multipart: Verify boundary limits for multipart body

It could happen that the boundary started at a place which resulted into
a negative number, which in an unsigned integer is a very large value.
Check the body size is not a negative value before setting it.

Closes https://gitlab.gnome.org/GNOME/libsoup/-/issues/449

Part-of: <https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/463>
---
libsoup/soup-multipart.c | 2 +-
tests/multipart-test.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/libsoup/soup-multipart.c b/libsoup/soup-multipart.c
index 102ce37..a587fe7 100644
--- a/libsoup/soup-multipart.c
+++ b/libsoup/soup-multipart.c
@@ -204,7 +204,7 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
*/
part_body = g_bytes_new_from_bytes (body, // FIXME
split - body_data,
- end - 2 - split);
+ end - 2 >= split ? end - 2 - split : 0);
g_ptr_array_add (multipart->bodies, part_body);

start = end;
diff --git a/tests/multipart-test.c b/tests/multipart-test.c
index ab5f41c..a3a0b36 100644
--- a/tests/multipart-test.c
+++ b/tests/multipart-test.c
@@ -527,6 +527,45 @@ test_multipart_bounds_bad (void)
g_bytes_unref (bytes);
}

+static void
+test_multipart_too_large (void)
+{
+ const char *raw_body =
+ "-------------------\r\n"
+ "-\n"
+ "Cont\"\r\n"
+ "Content-Tynt----e:n\x8erQK\r\n"
+ "Content-Disposition: name= form-; name=\"file\"; filename=\"ype:i/ -d; ----\xae\r\n"
+ "Content-Typimag\x01/png--\\\n"
+ "\r\n"
+ "---:\n\r\n"
+ "\r\n"
+ "-------------------------------------\r\n"
+ "---------\r\n"
+ "----------------------";
+ GBytes *body;
+ GHashTable *params;
+ SoupMessageHeaders *headers;
+ SoupMultipart *multipart;
+
+ params = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (params, (gpointer) "boundary", (gpointer) "-----------------");
+ headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
+ soup_message_headers_set_content_type (headers, "multipart/form-data", params);
+ g_hash_table_unref (params);
+
+ body = g_bytes_new_static (raw_body, strlen (raw_body));
+ multipart = soup_multipart_new_from_message (headers, body);
+ soup_message_headers_unref (headers);
+ g_bytes_unref (body);
+
+ g_assert_nonnull (multipart);
+ g_assert_cmpint (soup_multipart_get_length (multipart), ==, 1);
+ g_assert_true (soup_multipart_get_part (multipart, 0, &headers, &body));
+ g_assert_cmpint (g_bytes_get_size (body), ==, 0);
+ soup_multipart_free (multipart);
+}
+
int
main (int argc, char **argv)
{
@@ -556,6 +595,7 @@ main (int argc, char **argv)
g_test_add_data_func ("/multipart/async-small-reads", GINT_TO_POINTER (ASYNC_MULTIPART_SMALL_READS), test_multipart);
g_test_add_func ("/multipart/bounds-good", test_multipart_bounds_good);
g_test_add_func ("/multipart/bounds-bad", test_multipart_bounds_bad);
+ g_test_add_func ("/multipart/too-large", test_multipart_too_large);

ret = g_test_run ();

--
2.45.4

6 changes: 5 additions & 1 deletion SPECS/libsoup/libsoup.spec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Summary: libsoup HTTP client/server library
Name: libsoup
Version: 3.4.4
Release: 7%{?dist}
Release: 8%{?dist}
License: GPLv2
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand Down Expand Up @@ -65,6 +65,7 @@ Patch15: CVE-2025-46421.patch
Patch16: CVE-2025-32053.patch
Patch17: CVE-2025-4476.patch
Patch18: CVE-2025-32907.patch
Patch19: CVE-2025-4948.patch

%description
libsoup is HTTP client/server library for GNOME
Expand Down Expand Up @@ -132,6 +133,9 @@ find %{buildroot} -type f -name "*.la" -delete -print
%defattr(-,root,root)

%changelog
* Tue Jul 29 2025 Azure Linux Security Servicing Account <[email protected]> - 3.4.4-8
- Patch for CVE-2025-4948

* Fri Jun 13 2025 Kevin Lockwood <[email protected]> - 3.4.4-7
- Add patch for CVE-2025-4476
- Add patch for CVE-2025-32907
Expand Down
Binary file added libsoup/BUILD/.note.package.bin
Binary file not shown.
10 changes: 10 additions & 0 deletions libsoup/BUILD/auto_module_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _AUTO_MODULE_INFO_H_
#define _AUTO_MODULE_INFO_H_

#define MODULE_VERSION "3.4.4.0"
#define PACKAGE_VERSION "3.4.4-7.azl3"
#define PACKAGE_NAME "libsoup"
#define TARGET_OS "mariner"
#define TARGET_OS_VERSION "%{distro_release_version}"

#endif //_AUTO_MODULE_INFO_H_
1 change: 1 addition & 0 deletions libsoup/BUILD/libsoup-3.4.4
Submodule libsoup-3.4.4 added at b6fcdd
74 changes: 74 additions & 0 deletions libsoup/BUILD/module_info.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*

This file is automatically generated by generate-package-note.py tool.
Do not modify this file, your changes will be lost!

*/

/*
/usr/lib/rpm/azl/generate-package-note.py --os mariner --osVersion %{distro_release_version} --type rpm --name libsoup --version 3.4.4-7.azl3 --moduleVersion 3.4.4.0 --stamp LinkerOnly --outdir /mnt/vss/_work/1/s/autosec/azurelinux/libsoup/BUILD/
*/

/*
{
"moduleVersion": "3.4.4.0",
"name": "libsoup",
"os": "mariner",
"osVersion": "%{distro_release_version}",
"type": "rpm",
"version": "3.4.4-7.azl3"
}
*/

SECTIONS
{
.note.package (READONLY) : ALIGN(4)
{
BYTE(0x04) BYTE(0x00) BYTE(0x00) BYTE(0x00)
BYTE(0x9c) BYTE(0x00) BYTE(0x00) BYTE(0x00)
BYTE(0x7e) BYTE(0x1a) BYTE(0xfe) BYTE(0xca)
BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00)
BYTE(0x7b) BYTE(0x0a) BYTE(0x20) BYTE(0x22)
BYTE(0x6d) BYTE(0x6f) BYTE(0x64) BYTE(0x75)
BYTE(0x6c) BYTE(0x65) BYTE(0x56) BYTE(0x65)
BYTE(0x72) BYTE(0x73) BYTE(0x69) BYTE(0x6f)
BYTE(0x6e) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
BYTE(0x22) BYTE(0x33) BYTE(0x2e) BYTE(0x34)
BYTE(0x2e) BYTE(0x34) BYTE(0x2e) BYTE(0x30)
BYTE(0x22) BYTE(0x2c) BYTE(0x0a) BYTE(0x20)
BYTE(0x22) BYTE(0x6e) BYTE(0x61) BYTE(0x6d)
BYTE(0x65) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
BYTE(0x22) BYTE(0x6c) BYTE(0x69) BYTE(0x62)
BYTE(0x73) BYTE(0x6f) BYTE(0x75) BYTE(0x70)
BYTE(0x22) BYTE(0x2c) BYTE(0x0a) BYTE(0x20)
BYTE(0x22) BYTE(0x6f) BYTE(0x73) BYTE(0x22)
BYTE(0x3a) BYTE(0x20) BYTE(0x22) BYTE(0x6d)
BYTE(0x61) BYTE(0x72) BYTE(0x69) BYTE(0x6e)
BYTE(0x65) BYTE(0x72) BYTE(0x22) BYTE(0x2c)
BYTE(0x0a) BYTE(0x20) BYTE(0x22) BYTE(0x6f)
BYTE(0x73) BYTE(0x56) BYTE(0x65) BYTE(0x72)
BYTE(0x73) BYTE(0x69) BYTE(0x6f) BYTE(0x6e)
BYTE(0x22) BYTE(0x3a) BYTE(0x20) BYTE(0x22)
BYTE(0x25) BYTE(0x7b) BYTE(0x64) BYTE(0x69)
BYTE(0x73) BYTE(0x74) BYTE(0x72) BYTE(0x6f)
BYTE(0x5f) BYTE(0x72) BYTE(0x65) BYTE(0x6c)
BYTE(0x65) BYTE(0x61) BYTE(0x73) BYTE(0x65)
BYTE(0x5f) BYTE(0x76) BYTE(0x65) BYTE(0x72)
BYTE(0x73) BYTE(0x69) BYTE(0x6f) BYTE(0x6e)
BYTE(0x7d) BYTE(0x22) BYTE(0x2c) BYTE(0x0a)
BYTE(0x20) BYTE(0x22) BYTE(0x74) BYTE(0x79)
BYTE(0x70) BYTE(0x65) BYTE(0x22) BYTE(0x3a)
BYTE(0x20) BYTE(0x22) BYTE(0x72) BYTE(0x70)
BYTE(0x6d) BYTE(0x22) BYTE(0x2c) BYTE(0x0a)
BYTE(0x20) BYTE(0x22) BYTE(0x76) BYTE(0x65)
BYTE(0x72) BYTE(0x73) BYTE(0x69) BYTE(0x6f)
BYTE(0x6e) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
BYTE(0x22) BYTE(0x33) BYTE(0x2e) BYTE(0x34)
BYTE(0x2e) BYTE(0x34) BYTE(0x2d) BYTE(0x37)
BYTE(0x2e) BYTE(0x61) BYTE(0x7a) BYTE(0x6c)
BYTE(0x33) BYTE(0x22) BYTE(0x0a) BYTE(0x7d)

KEEP (*(.note.package))
}
}
INSERT AFTER .note.gnu.build-id;
1 change: 1 addition & 0 deletions libsoup/CVE-2025-4948/libsoup-3.4.4
Submodule libsoup-3.4.4 added at 14e00a
145 changes: 145 additions & 0 deletions libsoup/SOURCES/CVE-2024-52530.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
From 04df03bc092ac20607f3e150936624d4f536e68b Mon Sep 17 00:00:00 2001
From: Patrick Griffis <[email protected]>
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

Loading
Loading