summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2020-8285.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/curl/curl/CVE-2020-8285.patch')
-rw-r--r--meta/recipes-support/curl/curl/CVE-2020-8285.patch257
1 files changed, 257 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2020-8285.patch b/meta/recipes-support/curl/curl/CVE-2020-8285.patch
new file mode 100644
index 0000000000..8a0231ba84
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2020-8285.patch
@@ -0,0 +1,257 @@
1From 69a358f2186e04cf44698b5100332cbf1ee7f01d Mon Sep 17 00:00:00 2001
2From: Daniel Stenberg <daniel@haxx.se>
3Date: Sat, 28 Nov 2020 00:27:21 +0100
4Subject: [PATCH] ftp: make wc_statemach loop instead of recurse
5
6CVE-2020-8285
7
8Fixes #6255
9Bug: https://curl.se/docs/CVE-2020-8285.html
10Reported-by: xnynx on github
11
12Upstream-Status: Backport [https://github.com/curl/curl/commit/69a358f2186e04]
13
14CVE: CVE-2020-8285
15
16Signed-off-by: Daniel Stenberg <daniel@haxx.se>
17Signed-off-by: Khairul Rohaizzat Jamaluddin <khairul.rohaizzat.jamaluddin@intel.com>
18---
19 lib/ftp.c | 202 +++++++++++++++++++++++++++---------------------------
20 1 file changed, 102 insertions(+), 100 deletions(-)
21
22diff --git a/lib/ftp.c b/lib/ftp.c
23index 50e7d7ddac9..bc355742172 100644
24--- a/lib/ftp.c
25+++ b/lib/ftp.c
26@@ -3800,129 +3800,131 @@ static CURLcode init_wc_data(struct connectdata *conn)
27 return result;
28 }
29
30-/* This is called recursively */
31 static CURLcode wc_statemach(struct connectdata *conn)
32 {
33 struct WildcardData * const wildcard = &(conn->data->wildcard);
34 CURLcode result = CURLE_OK;
35
36- switch(wildcard->state) {
37- case CURLWC_INIT:
38- result = init_wc_data(conn);
39- if(wildcard->state == CURLWC_CLEAN)
40- /* only listing! */
41- break;
42- wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
43- break;
44+ for(;;) {
45+ switch(wildcard->state) {
46+ case CURLWC_INIT:
47+ result = init_wc_data(conn);
48+ if(wildcard->state == CURLWC_CLEAN)
49+ /* only listing! */
50+ return result;
51+ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
52+ return result;
53
54- case CURLWC_MATCHING: {
55- /* In this state is LIST response successfully parsed, so lets restore
56- previous WRITEFUNCTION callback and WRITEDATA pointer */
57- struct ftp_wc *ftpwc = wildcard->protdata;
58- conn->data->set.fwrite_func = ftpwc->backup.write_function;
59- conn->data->set.out = ftpwc->backup.file_descriptor;
60- ftpwc->backup.write_function = ZERO_NULL;
61- ftpwc->backup.file_descriptor = NULL;
62- wildcard->state = CURLWC_DOWNLOADING;
63-
64- if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
65- /* error found in LIST parsing */
66- wildcard->state = CURLWC_CLEAN;
67- return wc_statemach(conn);
68- }
69- if(wildcard->filelist.size == 0) {
70- /* no corresponding file */
71- wildcard->state = CURLWC_CLEAN;
72- return CURLE_REMOTE_FILE_NOT_FOUND;
73+ case CURLWC_MATCHING: {
74+ /* In this state is LIST response successfully parsed, so lets restore
75+ previous WRITEFUNCTION callback and WRITEDATA pointer */
76+ struct ftp_wc *ftpwc = wildcard->protdata;
77+ conn->data->set.fwrite_func = ftpwc->backup.write_function;
78+ conn->data->set.out = ftpwc->backup.file_descriptor;
79+ ftpwc->backup.write_function = ZERO_NULL;
80+ ftpwc->backup.file_descriptor = NULL;
81+ wildcard->state = CURLWC_DOWNLOADING;
82+
83+ if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
84+ /* error found in LIST parsing */
85+ wildcard->state = CURLWC_CLEAN;
86+ continue;
87+ }
88+ if(wildcard->filelist.size == 0) {
89+ /* no corresponding file */
90+ wildcard->state = CURLWC_CLEAN;
91+ return CURLE_REMOTE_FILE_NOT_FOUND;
92+ }
93+ continue;
94 }
95- return wc_statemach(conn);
96- }
97
98- case CURLWC_DOWNLOADING: {
99- /* filelist has at least one file, lets get first one */
100- struct ftp_conn *ftpc = &conn->proto.ftpc;
101- struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
102- struct FTP *ftp = conn->data->req.p.ftp;
103+ case CURLWC_DOWNLOADING: {
104+ /* filelist has at least one file, lets get first one */
105+ struct ftp_conn *ftpc = &conn->proto.ftpc;
106+ struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
107+ struct FTP *ftp = conn->data->req.p.ftp;
108
109- char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
110- if(!tmp_path)
111- return CURLE_OUT_OF_MEMORY;
112+ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
113+ if(!tmp_path)
114+ return CURLE_OUT_OF_MEMORY;
115
116- /* switch default ftp->path and tmp_path */
117- free(ftp->pathalloc);
118- ftp->pathalloc = ftp->path = tmp_path;
119-
120- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
121- if(conn->data->set.chunk_bgn) {
122- long userresponse;
123- Curl_set_in_callback(conn->data, true);
124- userresponse = conn->data->set.chunk_bgn(
125- finfo, wildcard->customptr, (int)wildcard->filelist.size);
126- Curl_set_in_callback(conn->data, false);
127- switch(userresponse) {
128- case CURL_CHUNK_BGN_FUNC_SKIP:
129- infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
130- finfo->filename);
131- wildcard->state = CURLWC_SKIP;
132- return wc_statemach(conn);
133- case CURL_CHUNK_BGN_FUNC_FAIL:
134- return CURLE_CHUNK_FAILED;
135+ /* switch default ftp->path and tmp_path */
136+ free(ftp->pathalloc);
137+ ftp->pathalloc = ftp->path = tmp_path;
138+
139+ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
140+ if(conn->data->set.chunk_bgn) {
141+ long userresponse;
142+ Curl_set_in_callback(conn->data, true);
143+ userresponse = conn->data->set.chunk_bgn(
144+ finfo, wildcard->customptr, (int)wildcard->filelist.size);
145+ Curl_set_in_callback(conn->data, false);
146+ switch(userresponse) {
147+ case CURL_CHUNK_BGN_FUNC_SKIP:
148+ infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
149+ finfo->filename);
150+ wildcard->state = CURLWC_SKIP;
151+ continue;
152+ case CURL_CHUNK_BGN_FUNC_FAIL:
153+ return CURLE_CHUNK_FAILED;
154+ }
155 }
156- }
157
158- if(finfo->filetype != CURLFILETYPE_FILE) {
159- wildcard->state = CURLWC_SKIP;
160- return wc_statemach(conn);
161- }
162+ if(finfo->filetype != CURLFILETYPE_FILE) {
163+ wildcard->state = CURLWC_SKIP;
164+ continue;
165+ }
166
167- if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
168- ftpc->known_filesize = finfo->size;
169+ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
170+ ftpc->known_filesize = finfo->size;
171
172- result = ftp_parse_url_path(conn);
173- if(result)
174- return result;
175+ result = ftp_parse_url_path(conn);
176+ if(result)
177+ return result;
178
179- /* we don't need the Curl_fileinfo of first file anymore */
180- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
181+ /* we don't need the Curl_fileinfo of first file anymore */
182+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
183
184- if(wildcard->filelist.size == 0) { /* remains only one file to down. */
185- wildcard->state = CURLWC_CLEAN;
186- /* after that will be ftp_do called once again and no transfer
187- will be done because of CURLWC_CLEAN state */
188- return CURLE_OK;
189+ if(wildcard->filelist.size == 0) { /* remains only one file to down. */
190+ wildcard->state = CURLWC_CLEAN;
191+ /* after that will be ftp_do called once again and no transfer
192+ will be done because of CURLWC_CLEAN state */
193+ return CURLE_OK;
194+ }
195+ return result;
196 }
197- } break;
198
199- case CURLWC_SKIP: {
200- if(conn->data->set.chunk_end) {
201- Curl_set_in_callback(conn->data, true);
202- conn->data->set.chunk_end(conn->data->wildcard.customptr);
203- Curl_set_in_callback(conn->data, false);
204+ case CURLWC_SKIP: {
205+ if(conn->data->set.chunk_end) {
206+ Curl_set_in_callback(conn->data, true);
207+ conn->data->set.chunk_end(conn->data->wildcard.customptr);
208+ Curl_set_in_callback(conn->data, false);
209+ }
210+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
211+ wildcard->state = (wildcard->filelist.size == 0) ?
212+ CURLWC_CLEAN : CURLWC_DOWNLOADING;
213+ continue;
214 }
215- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
216- wildcard->state = (wildcard->filelist.size == 0) ?
217- CURLWC_CLEAN : CURLWC_DOWNLOADING;
218- return wc_statemach(conn);
219- }
220
221- case CURLWC_CLEAN: {
222- struct ftp_wc *ftpwc = wildcard->protdata;
223- result = CURLE_OK;
224- if(ftpwc)
225- result = Curl_ftp_parselist_geterror(ftpwc->parser);
226+ case CURLWC_CLEAN: {
227+ struct ftp_wc *ftpwc = wildcard->protdata;
228+ result = CURLE_OK;
229+ if(ftpwc)
230+ result = Curl_ftp_parselist_geterror(ftpwc->parser);
231
232- wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
233- } break;
234+ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
235+ return result;
236+ }
237
238- case CURLWC_DONE:
239- case CURLWC_ERROR:
240- case CURLWC_CLEAR:
241- if(wildcard->dtor)
242- wildcard->dtor(wildcard->protdata);
243- break;
244+ case CURLWC_DONE:
245+ case CURLWC_ERROR:
246+ case CURLWC_CLEAR:
247+ if(wildcard->dtor)
248+ wildcard->dtor(wildcard->protdata);
249+ return result;
250+ }
251 }
252-
253- return result;
254+ /* UNREACHABLE */
255 }
256
257 /***********************************************************************