diff options
Diffstat (limited to 'meta/recipes-support/curl/curl/CVE-2020-8285.patch')
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2020-8285.patch | 260 |
1 files changed, 260 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..a66729b180 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2020-8285.patch | |||
@@ -0,0 +1,260 @@ | |||
1 | From 6fda045b19a9066701b5e09cfa657a13a3accbf3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Stenberg <daniel@haxx.se> | ||
3 | Date: Sat, 28 Nov 2020 00:27:21 +0100 | ||
4 | Subject: [PATCH] ftp: make wc_statemach loop instead of recurse | ||
5 | |||
6 | CVE-2020-8285 | ||
7 | |||
8 | Fixes #6255 | ||
9 | Bug: https://curl.se/docs/CVE-2020-8285.html | ||
10 | Reported-by: xnynx on github | ||
11 | |||
12 | Upstream-commit: 69a358f2186e04cf44698b5100332cbf1ee7f01d | ||
13 | Signed-off-by: Kamil Dudka <kdudka@redhat.com> | ||
14 | |||
15 | Upstream-Status: Backport [import from fedora https://koji.fedoraproject.org/koji/fileinfo?rpmID=24270817&filename=0006-curl-7.69.1-CVE-2020-8285.patch] | ||
16 | CVE: CVE-2020-8285 | ||
17 | Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com> | ||
18 | --- | ||
19 | lib/ftp.c | 202 +++++++++++++++++++++++++++--------------------------- | ||
20 | 1 file changed, 102 insertions(+), 100 deletions(-) | ||
21 | |||
22 | diff --git a/lib/ftp.c b/lib/ftp.c | ||
23 | index 57b22ad..3382772 100644 | ||
24 | --- a/lib/ftp.c | ||
25 | +++ b/lib/ftp.c | ||
26 | @@ -3763,129 +3763,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.protop; | ||
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.protop; | ||
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 | /*********************************************************************** | ||
258 | -- | ||
259 | 2.26.2 | ||
260 | |||