summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch')
-rw-r--r--meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch b/meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch
new file mode 100644
index 0000000000..99d42acb1e
--- /dev/null
+++ b/meta-oe/recipes-support/libsoup/libsoup-2.4/CVE-2026-2443.patch
@@ -0,0 +1,135 @@
1From 7bb3115a296154e3f465900ea5c984a493385a7f Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@gnome.org>
3Date: Fri, 19 Dec 2025 23:49:05 +0000
4Subject: [PATCH] Fix CVE-2026-2443
5
6Upstream-Status: Backport [
7c1796442 soup-message-headers: Rework Range response statuses to match Apache
8191ef313 soup-message-headers: Fix rejection of Range headers with trailing garbage
9be677bea soup-message-headers: Fix parsing of invalid Range suffix lengths
102bbfdfe8 soup-message-headers: Reject ranges where end is before start
11739bf7cb soup-message-headers: Reject invalid Range ends longer than the content
12]
13CVE: CVE-2026-2443
14
15Signed-off-by: Changqing Li <changqing.li@windriver.com>
16---
17 libsoup/soup-message-headers.c | 62 ++++++++++++++++++++++++----------
18 1 file changed, 44 insertions(+), 18 deletions(-)
19
20diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c
21index bb20bbb..535cf14 100644
22--- a/libsoup/soup-message-headers.c
23+++ b/libsoup/soup-message-headers.c
24@@ -943,10 +943,16 @@ sort_ranges (gconstpointer a, gconstpointer b)
25 }
26
27 /* like soup_message_headers_get_ranges(), except it returns:
28- * SOUP_STATUS_OK if there is no Range or it should be ignored.
29- * SOUP_STATUS_PARTIAL_CONTENT if there is at least one satisfiable range.
30- * SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE if @check_satisfiable
31- * is %TRUE and the request is not satisfiable given @total_length.
32+ * - SOUP_STATUS_OK if there is no Range or it should be ignored due to being
33+ * entirely invalid.
34+ * - SOUP_STATUS_PARTIAL_CONTENT if there is at least one satisfiable range.
35+ * - SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE if @check_satisfiable
36+ * is %TRUE, the Range is valid, but no part of the request is satisfiable
37+ * given @total_length.
38+ *
39+ * @ranges and @length are only set if SOUP_STATUS_PARTIAL_CONTENT is returned.
40+ *
41+ * See https://httpwg.org/specs/rfc9110.html#field.range
42 */
43 guint
44 soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs,
45@@ -960,22 +966,28 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs,
46 GArray *array;
47 char *spec, *end;
48 guint status = SOUP_STATUS_OK;
49+ gboolean is_all_valid = TRUE;
50
51 if (!range || strncmp (range, "bytes", 5) != 0)
52- return status;
53+ return SOUP_STATUS_OK; /* invalid header or unknown range unit */
54
55 range += 5;
56 while (g_ascii_isspace (*range))
57 range++;
58 if (*range++ != '=')
59- return status;
60+ return SOUP_STATUS_OK; /* invalid header */
61 while (g_ascii_isspace (*range))
62 range++;
63
64 range_list = soup_header_parse_list (range);
65 if (!range_list)
66- return status;
67+ return SOUP_STATUS_OK; /* invalid list */
68
69+ /* Loop through the ranges and modify the status accordingly. Default to
70+ * status 200 (OK, ignoring the ranges). Switch to status 206 (Partial
71+ * Content) if there is at least one partially valid range. Switch to
72+ * status 416 (Range Not Satisfiable) if there are no partially valid
73+ * ranges at all. */
74 array = g_array_new (FALSE, FALSE, sizeof (SoupRange));
75 for (r = range_list; r; r = r->next) {
76 SoupRange cur;
77@@ -988,30 +1000,44 @@ soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs,
78 cur.start = g_ascii_strtoull (spec, &end, 10);
79 if (*end == '-')
80 end++;
81- if (*end) {
82+ if (*end)
83 cur.end = g_ascii_strtoull (end, &end, 10);
84- if (cur.end < cur.start) {
85- status = SOUP_STATUS_OK;
86- break;
87- }
88- } else
89+ else
90 cur.end = total_length - 1;
91 }
92+
93 if (*end) {
94- status = SOUP_STATUS_OK;
95- break;
96- } else if (check_satisfiable && cur.start >= total_length) {
97- if (status == SOUP_STATUS_OK)
98- status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE;
99+ /* Junk after the range */
100+ is_all_valid = FALSE;
101+ continue;
102+ }
103+
104+ if (cur.end < cur.start) {
105+ is_all_valid = FALSE;
106+ continue;
107+ }
108+
109+ g_assert (cur.start >= 0);
110+ if (cur.end >= total_length)
111+ cur.end = total_length - 1;
112+
113+ if (cur.start >= total_length) {
114+ /* Range is valid, but unsatisfiable */
115 continue;
116 }
117
118+ /* We have at least one (at least partially) satisfiable range */
119 g_array_append_val (array, cur);
120 status = SOUP_STATUS_PARTIAL_CONTENT;
121 }
122 soup_header_free_list (range_list);
123
124 if (status != SOUP_STATUS_PARTIAL_CONTENT) {
125+ g_assert (status == SOUP_STATUS_OK);
126+
127+ if (is_all_valid && check_satisfiable)
128+ status = SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE;
129+
130 g_array_free (array, TRUE);
131 return status;
132 }
133--
1342.34.1
135