summaryrefslogtreecommitdiffstats
path: root/meta-networking
diff options
context:
space:
mode:
authorAnkur Tyagi <ankur.tyagi85@gmail.com>2025-12-16 12:45:32 +0530
committerAnuj Mittal <anuj.mittal@oss.qualcomm.com>2025-12-17 11:45:21 +0530
commiteb338ebb606f22363be5b4114e25a10b494b4f55 (patch)
tree7904281c1a43b0eec8cb2e01225cb55e58d58f9f /meta-networking
parent1c7b69ee0b6beb5f08c445af63ea5a3b4af77268 (diff)
downloadmeta-openembedded-eb338ebb606f22363be5b4114e25a10b494b4f55.tar.gz
civetweb: patch CVE-2025-9648
Details https://nvd.nist.gov/vuln/detail/CVE-2025-9648 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
Diffstat (limited to 'meta-networking')
-rw-r--r--meta-networking/recipes-connectivity/civetweb/civetweb/CVE-2025-9648.patch254
-rw-r--r--meta-networking/recipes-connectivity/civetweb/civetweb_1.16.bb1
2 files changed, 255 insertions, 0 deletions
diff --git a/meta-networking/recipes-connectivity/civetweb/civetweb/CVE-2025-9648.patch b/meta-networking/recipes-connectivity/civetweb/civetweb/CVE-2025-9648.patch
new file mode 100644
index 0000000000..0456203248
--- /dev/null
+++ b/meta-networking/recipes-connectivity/civetweb/civetweb/CVE-2025-9648.patch
@@ -0,0 +1,254 @@
1From 6f10111d24f9f7bdb637bba77c27700ecff56244 Mon Sep 17 00:00:00 2001
2From: bel2125 <bel2125@gmail.com>
3Date: Tue, 2 Sep 2025 14:08:41 +0200
4Subject: [PATCH] Make parsing of URL encoded forms more robust
5
6Reject requests that obviously violate the URL encoding.
7Fixes #1348
8
9CVE: CVE-2025-9648
10Upstream-Status: Backport [https://github.com/civetweb/civetweb/commit/782e18903515f43bafbf2e668994e82bdfa51133]
11(cherry picked from commit 782e18903515f43bafbf2e668994e82bdfa51133)
12Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
13---
14 src/civetweb.c | 7 ++++++-
15 src/handle_form.inl | 46 +++++++++++++++++++++++++++++++++++++--------
16 2 files changed, 44 insertions(+), 9 deletions(-)
17
18diff --git a/src/civetweb.c b/src/civetweb.c
19index 5452b36d..f843300c 100644
20--- a/src/civetweb.c
21+++ b/src/civetweb.c
22@@ -1,4 +1,4 @@
23-/* Copyright (c) 2013-2021 the Civetweb developers
24+/* Copyright (c) 2013-2025 the Civetweb developers
25 * Copyright (c) 2004-2013 Sergey Lyubka
26 *
27 * Permission is hereby granted, free of charge, to any person obtaining a copy
28@@ -7052,6 +7052,7 @@ mg_url_decode(const char *src,
29 int is_form_url_encoded)
30 {
31 int i, j, a, b;
32+
33 #define HEXTOI(x) (isdigit(x) ? (x - '0') : (x - 'W'))
34
35 for (i = j = 0; (i < src_len) && (j < (dst_len - 1)); i++, j++) {
36@@ -7064,11 +7065,15 @@ mg_url_decode(const char *src,
37 i += 2;
38 } else if (is_form_url_encoded && (src[i] == '+')) {
39 dst[j] = ' ';
40+ } else if ((unsigned char)src[i] <= ' ') {
41+ return -1; /* invalid character */
42 } else {
43 dst[j] = src[i];
44 }
45 }
46
47+#undef HEXTOI
48+
49 dst[j] = '\0'; /* Null-terminate the destination */
50
51 return (i >= src_len) ? j : -1;
52diff --git a/src/handle_form.inl b/src/handle_form.inl
53index be477a05..0ebaf560 100644
54--- a/src/handle_form.inl
55+++ b/src/handle_form.inl
56@@ -1,4 +1,4 @@
57-/* Copyright (c) 2016-2021 the Civetweb developers
58+/* Copyright (c) 2016-2025 the Civetweb developers
59 *
60 * Permission is hereby granted, free of charge, to any person obtaining a copy
61 * of this software and associated documentation files (the "Software"), to deal
62@@ -39,7 +39,7 @@ url_encoded_field_found(const struct mg_connection *conn,
63 mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
64
65 if (((size_t)key_dec_len >= (size_t)sizeof(key_dec)) || (key_dec_len < 0)) {
66- return MG_FORM_FIELD_STORAGE_SKIP;
67+ return MG_FORM_FIELD_STORAGE_ABORT;
68 }
69
70 if (filename) {
71@@ -53,7 +53,7 @@ url_encoded_field_found(const struct mg_connection *conn,
72 || (filename_dec_len < 0)) {
73 /* Log error message and skip this field. */
74 mg_cry_internal(conn, "%s: Cannot decode filename", __func__);
75- return MG_FORM_FIELD_STORAGE_SKIP;
76+ return MG_FORM_FIELD_STORAGE_ABORT;
77 }
78 remove_dot_segments(filename_dec);
79
80@@ -95,6 +95,7 @@ url_encoded_field_get(
81 struct mg_form_data_handler *fdh)
82 {
83 char key_dec[1024];
84+ int key_dec_len;
85
86 char *value_dec = (char *)mg_malloc_ctx(*value_len + 1, conn->phys_ctx);
87 int value_dec_len, ret;
88@@ -108,7 +109,8 @@ url_encoded_field_get(
89 return MG_FORM_FIELD_STORAGE_ABORT;
90 }
91
92- mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
93+ key_dec_len = mg_url_decode(
94+ key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
95
96 if (*value_len >= 2 && value[*value_len - 2] == '%')
97 *value_len -= 2;
98@@ -117,6 +119,11 @@ url_encoded_field_get(
99 value_dec_len = mg_url_decode(
100 value, (int)*value_len, value_dec, ((int)*value_len) + 1, 1);
101
102+ if ((key_dec_len < 0) || (value_dec_len < 0)) {
103+ mg_free(value_dec);
104+ return MG_FORM_FIELD_STORAGE_ABORT;
105+ }
106+
107 ret = fdh->field_get(key_dec,
108 value_dec,
109 (size_t)value_dec_len,
110@@ -136,9 +143,13 @@ unencoded_field_get(const struct mg_connection *conn,
111 struct mg_form_data_handler *fdh)
112 {
113 char key_dec[1024];
114+ int key_dec_len;
115 (void)conn;
116
117- mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
118+ key_dec_len = mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
119+ if (key_dec_len < 0) {
120+ return MG_FORM_FIELD_STORAGE_ABORT;
121+ }
122
123 return fdh->field_get(key_dec, value, value_len, fdh->user_data);
124 }
125@@ -188,6 +199,7 @@ mg_handle_form_request(struct mg_connection *conn,
126 int buf_fill = 0;
127 int r;
128 int field_count = 0;
129+ int abort_read = 0;
130 struct mg_file fstore = STRUCT_FILE_INITIALIZER;
131 int64_t file_size = 0; /* init here, to a avoid a false positive
132 "uninitialized variable used" warning */
133@@ -278,6 +290,7 @@ mg_handle_form_request(struct mg_connection *conn,
134 conn, data, (size_t)keylen, val, (size_t *)&vallen, fdh);
135 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
136 /* Stop request handling */
137+ abort_read = 1;
138 break;
139 }
140 if (r == MG_FORM_FIELD_HANDLE_NEXT) {
141@@ -320,6 +333,7 @@ mg_handle_form_request(struct mg_connection *conn,
142 r = field_stored(conn, path, file_size, fdh);
143 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
144 /* Stop request handling */
145+ abort_read = 1;
146 break;
147 }
148
149@@ -358,6 +372,7 @@ mg_handle_form_request(struct mg_connection *conn,
150 if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
151 == MG_FORM_FIELD_STORAGE_ABORT) {
152 /* Stop parsing the request */
153+ abort_read = 1;
154 break;
155 }
156
157@@ -386,7 +401,7 @@ mg_handle_form_request(struct mg_connection *conn,
158 * Here we use "POST", and read the data from the request body.
159 * The data read on the fly, so it is not required to buffer the
160 * entire request in memory before processing it. */
161- for (;;) {
162+ while (!abort_read) {
163 const char *val;
164 const char *next;
165 ptrdiff_t keylen, vallen;
166@@ -440,6 +455,7 @@ mg_handle_form_request(struct mg_connection *conn,
167 if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
168 == MG_FORM_FIELD_STORAGE_ABORT) {
169 /* Stop parsing the request */
170+ abort_read = 1;
171 break;
172 }
173
174@@ -468,6 +484,15 @@ mg_handle_form_request(struct mg_connection *conn,
175 } else {
176 vallen = (ptrdiff_t)strlen(val);
177 end_of_key_value_pair_found = all_data_read;
178+ if ((buf + buf_fill) > (val + vallen)) {
179+ /* Avoid DoS attacks by having a zero byte in the middle of
180+ * a request that is supposed to be URL encoded. Since this
181+ * request is certainly invalid, according to the protocol
182+ * specification, stop processing it. Fixes #1348 */
183+ abort_read = 1;
184+ break;
185+ }
186+
187 }
188
189 if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
190@@ -489,6 +514,7 @@ mg_handle_form_request(struct mg_connection *conn,
191 get_block++;
192 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
193 /* Stop request handling */
194+ abort_read = 1;
195 break;
196 }
197 if (r == MG_FORM_FIELD_HANDLE_NEXT) {
198@@ -557,7 +583,6 @@ mg_handle_form_request(struct mg_connection *conn,
199 val = buf;
200 }
201 }
202-
203 } while (!end_of_key_value_pair_found);
204
205 #if !defined(NO_FILESYSTEMS)
206@@ -568,6 +593,7 @@ mg_handle_form_request(struct mg_connection *conn,
207 r = field_stored(conn, path, file_size, fdh);
208 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
209 /* Stop request handling */
210+ abort_read = 1;
211 break;
212 }
213 } else {
214@@ -581,7 +607,7 @@ mg_handle_form_request(struct mg_connection *conn,
215 }
216 #endif /* NO_FILESYSTEMS */
217
218- if (all_data_read && (buf_fill == 0)) {
219+ if ((all_data_read && (buf_fill == 0)) || abort_read) {
220 /* nothing more to process */
221 break;
222 }
223@@ -937,6 +963,7 @@ mg_handle_form_request(struct mg_connection *conn,
224 get_block++;
225 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
226 /* Stop request handling */
227+ abort_read = 1;
228 break;
229 }
230 if (r == MG_FORM_FIELD_HANDLE_NEXT) {
231@@ -1011,6 +1038,7 @@ mg_handle_form_request(struct mg_connection *conn,
232 fdh);
233 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
234 /* Stop request handling */
235+ abort_read = 1;
236 break;
237 }
238 if (r == MG_FORM_FIELD_HANDLE_NEXT) {
239@@ -1039,6 +1067,7 @@ mg_handle_form_request(struct mg_connection *conn,
240 r = field_stored(conn, path, file_size, fdh);
241 if (r == MG_FORM_FIELD_HANDLE_ABORT) {
242 /* Stop request handling */
243+ abort_read = 1;
244 break;
245 }
246 } else {
247@@ -1057,6 +1086,7 @@ mg_handle_form_request(struct mg_connection *conn,
248 if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
249 == MG_FORM_FIELD_STORAGE_ABORT) {
250 /* Stop parsing the request */
251+ abort_read = 1;
252 break;
253 }
254
diff --git a/meta-networking/recipes-connectivity/civetweb/civetweb_1.16.bb b/meta-networking/recipes-connectivity/civetweb/civetweb_1.16.bb
index a546efca7b..0c860f85a3 100644
--- a/meta-networking/recipes-connectivity/civetweb/civetweb_1.16.bb
+++ b/meta-networking/recipes-connectivity/civetweb/civetweb_1.16.bb
@@ -9,6 +9,7 @@ SRCREV = "d7ba35bbb649209c66e582d5a0244ba988a15159"
9SRC_URI = "git://github.com/civetweb/civetweb.git;branch=master;protocol=https \ 9SRC_URI = "git://github.com/civetweb/civetweb.git;branch=master;protocol=https \
10 file://0001-Unittest-Link-librt-and-libm-using-l-option.patch \ 10 file://0001-Unittest-Link-librt-and-libm-using-l-option.patch \
11 file://0001-Fix-heap-overflow-in-directory-URI-slash-redirection.patch \ 11 file://0001-Fix-heap-overflow-in-directory-URI-slash-redirection.patch \
12 file://CVE-2025-9648.patch \
12 " 13 "
13 14
14S = "${WORKDIR}/git" 15S = "${WORKDIR}/git"