Skip to content

Commit 78a93d0

Browse files
Patch libsoup for CVE-2025-4948
1 parent 056d6fe commit 78a93d0

28 files changed

+2136
-1
lines changed

SPECS/libsoup/CVE-2025-4948.patch

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
From 14e00acc5167fc26a2bf71e2df6a754d340152cd Mon Sep 17 00:00:00 2001
2+
From: Milan Crha <[email protected]>
3+
Date: Thu, 15 May 2025 17:49:11 +0200
4+
Subject: [PATCH] soup-multipart: Verify boundary limits for multipart body
5+
6+
It could happen that the boundary started at a place which resulted into
7+
a negative number, which in an unsigned integer is a very large value.
8+
Check the body size is not a negative value before setting it.
9+
10+
Closes https://gitlab.gnome.org/GNOME/libsoup/-/issues/449
11+
12+
Part-of: <https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/463>
13+
---
14+
libsoup/soup-multipart.c | 2 +-
15+
tests/multipart-test.c | 40 ++++++++++++++++++++++++++++++++++++++++
16+
2 files changed, 41 insertions(+), 1 deletion(-)
17+
18+
diff --git a/libsoup/soup-multipart.c b/libsoup/soup-multipart.c
19+
index 102ce37..a587fe7 100644
20+
--- a/libsoup/soup-multipart.c
21+
+++ b/libsoup/soup-multipart.c
22+
@@ -204,7 +204,7 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
23+
*/
24+
part_body = g_bytes_new_from_bytes (body, // FIXME
25+
split - body_data,
26+
- end - 2 - split);
27+
+ end - 2 >= split ? end - 2 - split : 0);
28+
g_ptr_array_add (multipart->bodies, part_body);
29+
30+
start = end;
31+
diff --git a/tests/multipart-test.c b/tests/multipart-test.c
32+
index ab5f41c..a3a0b36 100644
33+
--- a/tests/multipart-test.c
34+
+++ b/tests/multipart-test.c
35+
@@ -527,6 +527,45 @@ test_multipart_bounds_bad (void)
36+
g_bytes_unref (bytes);
37+
}
38+
39+
+static void
40+
+test_multipart_too_large (void)
41+
+{
42+
+ const char *raw_body =
43+
+ "-------------------\r\n"
44+
+ "-\n"
45+
+ "Cont\"\r\n"
46+
+ "Content-Tynt----e:n\x8erQK\r\n"
47+
+ "Content-Disposition: name= form-; name=\"file\"; filename=\"ype:i/ -d; ----\xae\r\n"
48+
+ "Content-Typimag\x01/png--\\\n"
49+
+ "\r\n"
50+
+ "---:\n\r\n"
51+
+ "\r\n"
52+
+ "-------------------------------------\r\n"
53+
+ "---------\r\n"
54+
+ "----------------------";
55+
+ GBytes *body;
56+
+ GHashTable *params;
57+
+ SoupMessageHeaders *headers;
58+
+ SoupMultipart *multipart;
59+
+
60+
+ params = g_hash_table_new (g_str_hash, g_str_equal);
61+
+ g_hash_table_insert (params, (gpointer) "boundary", (gpointer) "-----------------");
62+
+ headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
63+
+ soup_message_headers_set_content_type (headers, "multipart/form-data", params);
64+
+ g_hash_table_unref (params);
65+
+
66+
+ body = g_bytes_new_static (raw_body, strlen (raw_body));
67+
+ multipart = soup_multipart_new_from_message (headers, body);
68+
+ soup_message_headers_unref (headers);
69+
+ g_bytes_unref (body);
70+
+
71+
+ g_assert_nonnull (multipart);
72+
+ g_assert_cmpint (soup_multipart_get_length (multipart), ==, 1);
73+
+ g_assert_true (soup_multipart_get_part (multipart, 0, &headers, &body));
74+
+ g_assert_cmpint (g_bytes_get_size (body), ==, 0);
75+
+ soup_multipart_free (multipart);
76+
+}
77+
+
78+
int
79+
main (int argc, char **argv)
80+
{
81+
@@ -556,6 +595,7 @@ main (int argc, char **argv)
82+
g_test_add_data_func ("/multipart/async-small-reads", GINT_TO_POINTER (ASYNC_MULTIPART_SMALL_READS), test_multipart);
83+
g_test_add_func ("/multipart/bounds-good", test_multipart_bounds_good);
84+
g_test_add_func ("/multipart/bounds-bad", test_multipart_bounds_bad);
85+
+ g_test_add_func ("/multipart/too-large", test_multipart_too_large);
86+
87+
ret = g_test_run ();
88+
89+
--
90+
2.45.4
91+

SPECS/libsoup/libsoup.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Summary: libsoup HTTP client/server library
55
Name: libsoup
66
Version: 3.4.4
7-
Release: 7%{?dist}
7+
Release: 8%{?dist}
88
License: GPLv2
99
Vendor: Microsoft Corporation
1010
Distribution: Azure Linux
@@ -65,6 +65,7 @@ Patch15: CVE-2025-46421.patch
6565
Patch16: CVE-2025-32053.patch
6666
Patch17: CVE-2025-4476.patch
6767
Patch18: CVE-2025-32907.patch
68+
Patch19: CVE-2025-4948.patch
6869

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

134135
%changelog
136+
* Tue Jul 29 2025 Azure Linux Security Servicing Account <[email protected]> - 3.4.4-8
137+
- Patch for CVE-2025-4948
138+
135139
* Fri Jun 13 2025 Kevin Lockwood <[email protected]> - 3.4.4-7
136140
- Add patch for CVE-2025-4476
137141
- Add patch for CVE-2025-32907

libsoup/BUILD/.note.package.bin

172 Bytes
Binary file not shown.

libsoup/BUILD/auto_module_info.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _AUTO_MODULE_INFO_H_
2+
#define _AUTO_MODULE_INFO_H_
3+
4+
#define MODULE_VERSION "3.4.4.0"
5+
#define PACKAGE_VERSION "3.4.4-7.azl3"
6+
#define PACKAGE_NAME "libsoup"
7+
#define TARGET_OS "mariner"
8+
#define TARGET_OS_VERSION "%{distro_release_version}"
9+
10+
#endif //_AUTO_MODULE_INFO_H_

libsoup/BUILD/libsoup-3.4.4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit b6fcdd01b4110850324e9af4e2e2b660853d614e

libsoup/BUILD/module_info.ld

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
3+
This file is automatically generated by generate-package-note.py tool.
4+
Do not modify this file, your changes will be lost!
5+
6+
*/
7+
8+
/*
9+
/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/
10+
*/
11+
12+
/*
13+
{
14+
"moduleVersion": "3.4.4.0",
15+
"name": "libsoup",
16+
"os": "mariner",
17+
"osVersion": "%{distro_release_version}",
18+
"type": "rpm",
19+
"version": "3.4.4-7.azl3"
20+
}
21+
*/
22+
23+
SECTIONS
24+
{
25+
.note.package (READONLY) : ALIGN(4)
26+
{
27+
BYTE(0x04) BYTE(0x00) BYTE(0x00) BYTE(0x00)
28+
BYTE(0x9c) BYTE(0x00) BYTE(0x00) BYTE(0x00)
29+
BYTE(0x7e) BYTE(0x1a) BYTE(0xfe) BYTE(0xca)
30+
BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00)
31+
BYTE(0x7b) BYTE(0x0a) BYTE(0x20) BYTE(0x22)
32+
BYTE(0x6d) BYTE(0x6f) BYTE(0x64) BYTE(0x75)
33+
BYTE(0x6c) BYTE(0x65) BYTE(0x56) BYTE(0x65)
34+
BYTE(0x72) BYTE(0x73) BYTE(0x69) BYTE(0x6f)
35+
BYTE(0x6e) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
36+
BYTE(0x22) BYTE(0x33) BYTE(0x2e) BYTE(0x34)
37+
BYTE(0x2e) BYTE(0x34) BYTE(0x2e) BYTE(0x30)
38+
BYTE(0x22) BYTE(0x2c) BYTE(0x0a) BYTE(0x20)
39+
BYTE(0x22) BYTE(0x6e) BYTE(0x61) BYTE(0x6d)
40+
BYTE(0x65) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
41+
BYTE(0x22) BYTE(0x6c) BYTE(0x69) BYTE(0x62)
42+
BYTE(0x73) BYTE(0x6f) BYTE(0x75) BYTE(0x70)
43+
BYTE(0x22) BYTE(0x2c) BYTE(0x0a) BYTE(0x20)
44+
BYTE(0x22) BYTE(0x6f) BYTE(0x73) BYTE(0x22)
45+
BYTE(0x3a) BYTE(0x20) BYTE(0x22) BYTE(0x6d)
46+
BYTE(0x61) BYTE(0x72) BYTE(0x69) BYTE(0x6e)
47+
BYTE(0x65) BYTE(0x72) BYTE(0x22) BYTE(0x2c)
48+
BYTE(0x0a) BYTE(0x20) BYTE(0x22) BYTE(0x6f)
49+
BYTE(0x73) BYTE(0x56) BYTE(0x65) BYTE(0x72)
50+
BYTE(0x73) BYTE(0x69) BYTE(0x6f) BYTE(0x6e)
51+
BYTE(0x22) BYTE(0x3a) BYTE(0x20) BYTE(0x22)
52+
BYTE(0x25) BYTE(0x7b) BYTE(0x64) BYTE(0x69)
53+
BYTE(0x73) BYTE(0x74) BYTE(0x72) BYTE(0x6f)
54+
BYTE(0x5f) BYTE(0x72) BYTE(0x65) BYTE(0x6c)
55+
BYTE(0x65) BYTE(0x61) BYTE(0x73) BYTE(0x65)
56+
BYTE(0x5f) BYTE(0x76) BYTE(0x65) BYTE(0x72)
57+
BYTE(0x73) BYTE(0x69) BYTE(0x6f) BYTE(0x6e)
58+
BYTE(0x7d) BYTE(0x22) BYTE(0x2c) BYTE(0x0a)
59+
BYTE(0x20) BYTE(0x22) BYTE(0x74) BYTE(0x79)
60+
BYTE(0x70) BYTE(0x65) BYTE(0x22) BYTE(0x3a)
61+
BYTE(0x20) BYTE(0x22) BYTE(0x72) BYTE(0x70)
62+
BYTE(0x6d) BYTE(0x22) BYTE(0x2c) BYTE(0x0a)
63+
BYTE(0x20) BYTE(0x22) BYTE(0x76) BYTE(0x65)
64+
BYTE(0x72) BYTE(0x73) BYTE(0x69) BYTE(0x6f)
65+
BYTE(0x6e) BYTE(0x22) BYTE(0x3a) BYTE(0x20)
66+
BYTE(0x22) BYTE(0x33) BYTE(0x2e) BYTE(0x34)
67+
BYTE(0x2e) BYTE(0x34) BYTE(0x2d) BYTE(0x37)
68+
BYTE(0x2e) BYTE(0x61) BYTE(0x7a) BYTE(0x6c)
69+
BYTE(0x33) BYTE(0x22) BYTE(0x0a) BYTE(0x7d)
70+
71+
KEEP (*(.note.package))
72+
}
73+
}
74+
INSERT AFTER .note.gnu.build-id;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 14e00acc5167fc26a2bf71e2df6a754d340152cd
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
From 04df03bc092ac20607f3e150936624d4f536e68b Mon Sep 17 00:00:00 2001
2+
From: Patrick Griffis <[email protected]>
3+
Date: Mon, 8 Jul 2024 12:33:15 -0500
4+
Subject: [PATCH] headers: Strictly don't allow NUL bytes
5+
6+
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.
7+
---
8+
libsoup/soup-headers.c | 15 +++------
9+
tests/header-parsing-test.c | 62 +++++++++++++++++--------------------
10+
2 files changed, 32 insertions(+), 45 deletions(-)
11+
12+
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
13+
index a0cf351ac..f30ee467a 100644
14+
--- a/libsoup/soup-headers.c
15+
+++ b/libsoup/soup-headers.c
16+
@@ -51,13 +51,14 @@ soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
17+
* ignorable trailing whitespace.
18+
*/
19+
20+
+ /* No '\0's are allowed */
21+
+ if (memchr (str, '\0', len))
22+
+ return FALSE;
23+
+
24+
/* Skip over the Request-Line / Status-Line */
25+
headers_start = memchr (str, '\n', len);
26+
if (!headers_start)
27+
return FALSE;
28+
- /* No '\0's in the Request-Line / Status-Line */
29+
- if (memchr (str, '\0', headers_start - str))
30+
- return FALSE;
31+
32+
/* We work on a copy of the headers, which we can write '\0's
33+
* into, so that we don't have to individually g_strndup and
34+
@@ -69,14 +70,6 @@ soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
35+
headers_copy[copy_len] = '\0';
36+
value_end = headers_copy;
37+
38+
- /* There shouldn't be any '\0's in the headers already, but
39+
- * this is the web we're talking about.
40+
- */
41+
- while ((p = memchr (headers_copy, '\0', copy_len))) {
42+
- memmove (p, p + 1, copy_len - (p - headers_copy));
43+
- copy_len--;
44+
- }
45+
-
46+
while (*(value_end + 1)) {
47+
name = value_end + 1;
48+
name_end = strchr (name, ':');
49+
diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c
50+
index edf8eebb3..715c2c6f2 100644
51+
--- a/tests/header-parsing-test.c
52+
+++ b/tests/header-parsing-test.c
53+
@@ -358,24 +358,6 @@ static struct RequestTest {
54+
}
55+
},
56+
57+
- { "NUL in header name", "760832",
58+
- "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36,
59+
- SOUP_STATUS_OK,
60+
- "GET", "/", SOUP_HTTP_1_1,
61+
- { { "Host", "example.com" },
62+
- { NULL }
63+
- }
64+
- },
65+
-
66+
- { "NUL in header value", "760832",
67+
- "GET / HTTP/1.1\r\nHost: example\x00" "com\r\n", 35,
68+
- SOUP_STATUS_OK,
69+
- "GET", "/", SOUP_HTTP_1_1,
70+
- { { "Host", "examplecom" },
71+
- { NULL }
72+
- }
73+
- },
74+
-
75+
/************************/
76+
/*** INVALID REQUESTS ***/
77+
/************************/
78+
@@ -448,6 +430,21 @@ static struct RequestTest {
79+
SOUP_STATUS_EXPECTATION_FAILED,
80+
NULL, NULL, -1,
81+
{ { NULL } }
82+
+ },
83+
+
84+
+ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377
85+
+ { "NUL in header name", NULL,
86+
+ "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36,
87+
+ SOUP_STATUS_BAD_REQUEST,
88+
+ NULL, NULL, -1,
89+
+ { { NULL } }
90+
+ },
91+
+
92+
+ { "NUL in header value", NULL,
93+
+ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
94+
+ SOUP_STATUS_BAD_REQUEST,
95+
+ NULL, NULL, -1,
96+
+ { { NULL } }
97+
}
98+
};
99+
static const int num_reqtests = G_N_ELEMENTS (reqtests);
100+
@@ -620,22 +617,6 @@ static struct ResponseTest {
101+
{ NULL } }
102+
},
103+
104+
- { "NUL in header name", "760832",
105+
- "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28,
106+
- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK",
107+
- { { "Foo", "bar" },
108+
- { NULL }
109+
- }
110+
- },
111+
-
112+
- { "NUL in header value", "760832",
113+
- "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
114+
- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK",
115+
- { { "Foo", "bar" },
116+
- { NULL }
117+
- }
118+
- },
119+
-
120+
/********************************/
121+
/*** VALID CONTINUE RESPONSES ***/
122+
/********************************/
123+
@@ -768,6 +749,19 @@ static struct ResponseTest {
124+
{ { NULL }
125+
}
126+
},
127+
+
128+
+ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377
129+
+ { "NUL in header name", NULL,
130+
+ "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28,
131+
+ -1, 0, NULL,
132+
+ { { NULL } }
133+
+ },
134+
+
135+
+ { "NUL in header value", "760832",
136+
+ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28,
137+
+ -1, 0, NULL,
138+
+ { { NULL } }
139+
+ },
140+
};
141+
static const int num_resptests = G_N_ELEMENTS (resptests);
142+
143+
--
144+
GitLab
145+

0 commit comments

Comments
 (0)