summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2016-09-18 05:33:07 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-09-23 22:22:03 (GMT)
commit661aff850ec55fdd3a73904417efb303dfdab51f (patch)
tree164c8800bbbe8cf2dcf0d06a17bbe143d43d2e1d
parent8f62c3dc446b7c6a43b798f73aa44acf50f00195 (diff)
downloadpoky-661aff850ec55fdd3a73904417efb303dfdab51f.tar.gz
wget: Security fix CVE-2016-4971
affects wget < 1.18.0 (From OE-Core rev: 15b6586ae64f745777ba5c42f4cf055aeeed83d8) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/wget/wget/CVE-2016-4971.patch294
-rw-r--r--meta/recipes-extended/wget/wget/Fix-timestamping-and-continue-behaviour-with-ftp-pro.patch108
-rw-r--r--meta/recipes-extended/wget/wget_1.16.3.bb2
3 files changed, 404 insertions, 0 deletions
diff --git a/meta/recipes-extended/wget/wget/CVE-2016-4971.patch b/meta/recipes-extended/wget/wget/CVE-2016-4971.patch
new file mode 100644
index 0000000..62583d9
--- /dev/null
+++ b/meta/recipes-extended/wget/wget/CVE-2016-4971.patch
@@ -0,0 +1,294 @@
1From e996e322ffd42aaa051602da182d03178d0f13e1 Mon Sep 17 00:00:00 2001
2From: Giuseppe Scrivano <gscrivan@redhat.com>
3Date: Mon, 6 Jun 2016 21:20:24 +0200
4Subject: [PATCH] ftp: understand --trust-server-names on a HTTP->FTP redirect
5
6If not --trust-server-names is used, FTP will also get the destination
7file name from the original url specified by the user instead of the
8redirected url. Closes CVE-2016-4971.
9
10* src/ftp.c (ftp_get_listing): Add argument original_url.
11(getftp): Likewise.
12(ftp_loop_internal): Likewise. Use original_url to generate the
13file name if --trust-server-names is not provided.
14(ftp_retrieve_glob): Likewise.
15(ftp_loop): Likewise.
16
17Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
18
19Upstream-Status: Backport
20CVE: CVE-2016-4971
21Signed-off-by: Armin Kuster <akuster@mvista.com>
22
23---
24 src/ftp.c | 71 +++++++++++++++++++++++++++++++++++++-------------------------
25 src/ftp.h | 3 ++-
26 src/retr.c | 3 ++-
27 3 files changed, 47 insertions(+), 30 deletions(-)
28
29Index: wget-1.16.3/src/ftp.c
30===================================================================
31--- wget-1.16.3.orig/src/ftp.c
32+++ wget-1.16.3/src/ftp.c
33@@ -235,14 +235,15 @@ print_length (wgint size, wgint start, b
34 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
35 }
36
37-static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
38+static uerr_t ftp_get_listing (struct url *, struct url *, ccon *, struct fileinfo **);
39
40 /* Retrieves a file with denoted parameters through opening an FTP
41 connection to the server. It always closes the data connection,
42 and closes the control connection in case of error. If warc_tmp
43 is non-NULL, the downloaded data will be written there as well. */
44 static uerr_t
45-getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
46+getftp (struct url *u, struct url *original_url,
47+ wgint passed_expected_bytes, wgint *qtyread,
48 wgint restval, ccon *con, int count, wgint *last_expected_bytes,
49 FILE *warc_tmp)
50 {
51@@ -996,7 +997,7 @@ Error in server response, closing contro
52 {
53 bool exists = false;
54 struct fileinfo *f;
55- uerr_t _res = ftp_get_listing (u, con, &f);
56+ uerr_t _res = ftp_get_listing (u, original_url, con, &f);
57 /* Set the DO_RETR command flag again, because it gets unset when
58 calling ftp_get_listing() and would otherwise cause an assertion
59 failure earlier on when this function gets repeatedly called
60@@ -1540,8 +1541,8 @@ Error in server response, closing contro
61 This loop either gets commands from con, or (if ON_YOUR_OWN is
62 set), makes them up to retrieve the file given by the URL. */
63 static uerr_t
64-ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file,
65- bool force_full_retrieve)
66+ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f,
67+ ccon *con, char **local_file, bool force_full_retrieve)
68 {
69 int count, orig_lp;
70 wgint restval, len = 0, qtyread = 0;
71@@ -1566,7 +1567,7 @@ ftp_loop_internal (struct url *u, struct
72 {
73 /* URL-derived file. Consider "-O file" name. */
74 xfree (con->target);
75- con->target = url_file_name (u, NULL);
76+ con->target = url_file_name (opt.trustservernames || !original_url ? u : original_url, NULL);
77 if (!opt.output_document)
78 locf = con->target;
79 else
80@@ -1684,8 +1685,8 @@ ftp_loop_internal (struct url *u, struct
81
82 /* If we are working on a WARC record, getftp should also write
83 to the warc_tmp file. */
84- err = getftp (u, len, &qtyread, restval, con, count, &last_expected_bytes,
85- warc_tmp);
86+ err = getftp (u, original_url, len, &qtyread, restval, con, count,
87+ &last_expected_bytes, warc_tmp);
88
89 if (con->csock == -1)
90 con->st &= ~DONE_CWD;
91@@ -1838,7 +1839,8 @@ Removing file due to --delete-after in f
92 /* Return the directory listing in a reusable format. The directory
93 is specifed in u->dir. */
94 static uerr_t
95-ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
96+ftp_get_listing (struct url *u, struct url *original_url, ccon *con,
97+ struct fileinfo **f)
98 {
99 uerr_t err;
100 char *uf; /* url file name */
101@@ -1859,7 +1861,7 @@ ftp_get_listing (struct url *u, ccon *co
102
103 con->target = xstrdup (lf);
104 xfree (lf);
105- err = ftp_loop_internal (u, NULL, con, NULL, false);
106+ err = ftp_loop_internal (u, original_url, NULL, con, NULL, false);
107 lf = xstrdup (con->target);
108 xfree (con->target);
109 con->target = old_target;
110@@ -1882,8 +1884,9 @@ ftp_get_listing (struct url *u, ccon *co
111 return err;
112 }
113
114-static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
115-static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
116+static uerr_t ftp_retrieve_dirs (struct url *, struct url *,
117+ struct fileinfo *, ccon *);
118+static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int);
119 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
120 static void freefileinfo (struct fileinfo *f);
121
122@@ -1895,7 +1898,8 @@ static void freefileinfo (struct fileinf
123 If opt.recursive is set, after all files have been retrieved,
124 ftp_retrieve_dirs will be called to retrieve the directories. */
125 static uerr_t
126-ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
127+ftp_retrieve_list (struct url *u, struct url *original_url,
128+ struct fileinfo *f, ccon *con)
129 {
130 static int depth = 0;
131 uerr_t err;
132@@ -2056,7 +2060,10 @@ Already have correct symlink %s -> %s\n\
133 else /* opt.retr_symlinks */
134 {
135 if (dlthis)
136- err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
137+ {
138+ err = ftp_loop_internal (u, original_url, f, con, NULL,
139+ force_full_retrieve);
140+ }
141 } /* opt.retr_symlinks */
142 break;
143 case FT_DIRECTORY:
144@@ -2067,7 +2074,10 @@ Already have correct symlink %s -> %s\n\
145 case FT_PLAINFILE:
146 /* Call the retrieve loop. */
147 if (dlthis)
148- err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
149+ {
150+ err = ftp_loop_internal (u, original_url, f, con, NULL,
151+ force_full_retrieve);
152+ }
153 break;
154 case FT_UNKNOWN:
155 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
156@@ -2132,7 +2142,7 @@ Already have correct symlink %s -> %s\n\
157 /* We do not want to call ftp_retrieve_dirs here */
158 if (opt.recursive &&
159 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
160- err = ftp_retrieve_dirs (u, orig, con);
161+ err = ftp_retrieve_dirs (u, original_url, orig, con);
162 else if (opt.recursive)
163 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
164 depth, opt.reclevel));
165@@ -2145,7 +2155,8 @@ Already have correct symlink %s -> %s\n\
166 ftp_retrieve_glob on each directory entry. The function knows
167 about excluded directories. */
168 static uerr_t
169-ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
170+ftp_retrieve_dirs (struct url *u, struct url *original_url,
171+ struct fileinfo *f, ccon *con)
172 {
173 char *container = NULL;
174 int container_size = 0;
175@@ -2195,7 +2206,7 @@ Not descending to %s as it is excluded/n
176 odir = xstrdup (u->dir); /* because url_set_dir will free
177 u->dir. */
178 url_set_dir (u, newdir);
179- ftp_retrieve_glob (u, con, GLOB_GETALL);
180+ ftp_retrieve_glob (u, original_url, con, GLOB_GETALL);
181 url_set_dir (u, odir);
182 xfree (odir);
183
184@@ -2254,14 +2265,15 @@ is_invalid_entry (struct fileinfo *f)
185 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
186 directory. */
187 static uerr_t
188-ftp_retrieve_glob (struct url *u, ccon *con, int action)
189+ftp_retrieve_glob (struct url *u, struct url *original_url,
190+ ccon *con, int action)
191 {
192 struct fileinfo *f, *start;
193 uerr_t res;
194
195 con->cmd |= LEAVE_PENDING;
196
197- res = ftp_get_listing (u, con, &start);
198+ res = ftp_get_listing (u, original_url, con, &start);
199 if (res != RETROK)
200 return res;
201 /* First: weed out that do not conform the global rules given in
202@@ -2357,7 +2369,7 @@ ftp_retrieve_glob (struct url *u, ccon *
203 if (start)
204 {
205 /* Just get everything. */
206- res = ftp_retrieve_list (u, start, con);
207+ res = ftp_retrieve_list (u, original_url, start, con);
208 }
209 else
210 {
211@@ -2373,7 +2385,7 @@ ftp_retrieve_glob (struct url *u, ccon *
212 {
213 /* Let's try retrieving it anyway. */
214 con->st |= ON_YOUR_OWN;
215- res = ftp_loop_internal (u, NULL, con, NULL, false);
216+ res = ftp_loop_internal (u, original_url, NULL, con, NULL, false);
217 return res;
218 }
219
220@@ -2393,8 +2405,8 @@ ftp_retrieve_glob (struct url *u, ccon *
221 of URL. Inherently, its capabilities are limited on what can be
222 encoded into a URL. */
223 uerr_t
224-ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
225- bool recursive, bool glob)
226+ftp_loop (struct url *u, struct url *original_url, char **local_file, int *dt,
227+ struct url *proxy, bool recursive, bool glob)
228 {
229 ccon con; /* FTP connection */
230 uerr_t res;
231@@ -2415,16 +2427,17 @@ ftp_loop (struct url *u, char **local_fi
232 if (!*u->file && !recursive)
233 {
234 struct fileinfo *f;
235- res = ftp_get_listing (u, &con, &f);
236+ res = ftp_get_listing (u, original_url, &con, &f);
237
238 if (res == RETROK)
239 {
240 if (opt.htmlify && !opt.spider)
241 {
242+ struct url *url_file = opt.trustservernames ? u : original_url;
243 char *filename = (opt.output_document
244 ? xstrdup (opt.output_document)
245 : (con.target ? xstrdup (con.target)
246- : url_file_name (u, NULL)));
247+ : url_file_name (url_file, NULL)));
248 res = ftp_index (filename, u, f);
249 if (res == FTPOK && opt.verbose)
250 {
251@@ -2469,11 +2482,13 @@ ftp_loop (struct url *u, char **local_fi
252 /* ftp_retrieve_glob is a catch-all function that gets called
253 if we need globbing, time-stamping, recursion or preserve
254 permissions. Its third argument is just what we really need. */
255- res = ftp_retrieve_glob (u, &con,
256+ res = ftp_retrieve_glob (u, original_url, &con,
257 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
258 }
259 else
260- res = ftp_loop_internal (u, NULL, &con, local_file, false);
261+ {
262+ res = ftp_loop_internal (u, original_url, NULL, &con, local_file, false);
263+ }
264 }
265 if (res == FTPOK)
266 res = RETROK;
267Index: wget-1.16.3/src/ftp.h
268===================================================================
269--- wget-1.16.3.orig/src/ftp.h
270+++ wget-1.16.3/src/ftp.h
271@@ -150,7 +150,8 @@ enum wget_ftp_fstatus
272 };
273
274 struct fileinfo *ftp_parse_ls (const char *, const enum stype);
275-uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
276+uerr_t ftp_loop (struct url *, struct url *, char **, int *, struct url *,
277+ bool, bool);
278
279 uerr_t ftp_index (const char *, struct url *, struct fileinfo *);
280
281Index: wget-1.16.3/src/retr.c
282===================================================================
283--- wget-1.16.3.orig/src/retr.c
284+++ wget-1.16.3/src/retr.c
285@@ -807,7 +807,8 @@ retrieve_url (struct url * orig_parsed,
286 if (redirection_count)
287 oldrec = glob = false;
288
289- result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob);
290+ result = ftp_loop (u, orig_parsed, &local_file, dt, proxy_url,
291+ recursive, glob);
292 recursive = oldrec;
293
294 /* There is a possibility of having HTTP being redirected to
diff --git a/meta/recipes-extended/wget/wget/Fix-timestamping-and-continue-behaviour-with-ftp-pro.patch b/meta/recipes-extended/wget/wget/Fix-timestamping-and-continue-behaviour-with-ftp-pro.patch
new file mode 100644
index 0000000..a63b6c2
--- /dev/null
+++ b/meta/recipes-extended/wget/wget/Fix-timestamping-and-continue-behaviour-with-ftp-pro.patch
@@ -0,0 +1,108 @@
1From 0e6d6ca963f13e0c4d239cd9e7aea62d176da8eb Mon Sep 17 00:00:00 2001
2From: Nikolay Merinov <kim.roader@gmail.com>
3Date: Fri, 17 Apr 2015 23:32:30 +0500
4Subject: [PATCH] Fix timestamping and continue behaviour with ftp protocol.
5
6* src/ftp.c (ftp_loop_internal): Add option `force_full_retrieve' that force to
7retrieve full file.
8(ftp_retrieve_list): Pass `true' as `force_full_retrieve' option to
9`ftp_loop_internal' if we want to download file with newer timestamp than local
10copy.
11
12Upstream-Status: Backport
13In support of CVE-2016-4971
14Signed-off-by: Armin Kuster <akuster@mvista.com>
15
16---
17 src/ftp.c | 21 +++++++++++++--------
18 1 file changed, 13 insertions(+), 8 deletions(-)
19
20Index: wget-1.16.3/src/ftp.c
21===================================================================
22--- wget-1.16.3.orig/src/ftp.c
23+++ wget-1.16.3/src/ftp.c
24@@ -1540,7 +1540,8 @@ Error in server response, closing contro
25 This loop either gets commands from con, or (if ON_YOUR_OWN is
26 set), makes them up to retrieve the file given by the URL. */
27 static uerr_t
28-ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
29+ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file,
30+ bool force_full_retrieve)
31 {
32 int count, orig_lp;
33 wgint restval, len = 0, qtyread = 0;
34@@ -1642,6 +1643,8 @@ ftp_loop_internal (struct url *u, struct
35 /* Decide whether or not to restart. */
36 if (con->cmd & DO_LIST)
37 restval = 0;
38+ else if (force_full_retrieve)
39+ restval = 0;
40 else if (opt.start_pos >= 0)
41 restval = opt.start_pos;
42 else if (opt.always_rest
43@@ -1856,7 +1859,7 @@ ftp_get_listing (struct url *u, ccon *co
44
45 con->target = xstrdup (lf);
46 xfree (lf);
47- err = ftp_loop_internal (u, NULL, con, NULL);
48+ err = ftp_loop_internal (u, NULL, con, NULL, false);
49 lf = xstrdup (con->target);
50 xfree (con->target);
51 con->target = old_target;
52@@ -1901,6 +1904,7 @@ ftp_retrieve_list (struct url *u, struct
53 time_t tml;
54 bool dlthis; /* Download this (file). */
55 const char *actual_target = NULL;
56+ bool force_full_retrieve = false;
57
58 /* Increase the depth. */
59 ++depth;
60@@ -1980,9 +1984,10 @@ ftp_retrieve_list (struct url *u, struct
61 Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
62 dlthis = false;
63 }
64- else if (eq_size)
65+ else if (f->tstamp > tml)
66 {
67- /* Remote file is newer or sizes cannot be matched */
68+ /* Remote file is newer */
69+ force_full_retrieve = true;
70 logprintf (LOG_VERBOSE, _("\
71 Remote file is newer than local file %s -- retrieving.\n\n"),
72 quote (con->target));
73@@ -2051,7 +2056,7 @@ Already have correct symlink %s -> %s\n\
74 else /* opt.retr_symlinks */
75 {
76 if (dlthis)
77- err = ftp_loop_internal (u, f, con, NULL);
78+ err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
79 } /* opt.retr_symlinks */
80 break;
81 case FT_DIRECTORY:
82@@ -2062,7 +2067,7 @@ Already have correct symlink %s -> %s\n\
83 case FT_PLAINFILE:
84 /* Call the retrieve loop. */
85 if (dlthis)
86- err = ftp_loop_internal (u, f, con, NULL);
87+ err = ftp_loop_internal (u, f, con, NULL, force_full_retrieve);
88 break;
89 case FT_UNKNOWN:
90 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
91@@ -2368,7 +2373,7 @@ ftp_retrieve_glob (struct url *u, ccon *
92 {
93 /* Let's try retrieving it anyway. */
94 con->st |= ON_YOUR_OWN;
95- res = ftp_loop_internal (u, NULL, con, NULL);
96+ res = ftp_loop_internal (u, NULL, con, NULL, false);
97 return res;
98 }
99
100@@ -2468,7 +2473,7 @@ ftp_loop (struct url *u, char **local_fi
101 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
102 }
103 else
104- res = ftp_loop_internal (u, NULL, &con, local_file);
105+ res = ftp_loop_internal (u, NULL, &con, local_file, false);
106 }
107 if (res == FTPOK)
108 res = RETROK;
diff --git a/meta/recipes-extended/wget/wget_1.16.3.bb b/meta/recipes-extended/wget/wget_1.16.3.bb
index 5c34a42..0204f30 100644
--- a/meta/recipes-extended/wget/wget_1.16.3.bb
+++ b/meta/recipes-extended/wget/wget_1.16.3.bb
@@ -1,6 +1,8 @@
1SRC_URI = "${GNU_MIRROR}/wget/wget-${PV}.tar.gz \ 1SRC_URI = "${GNU_MIRROR}/wget/wget-${PV}.tar.gz \
2 file://fix_makefile.patch \ 2 file://fix_makefile.patch \
3 file://0001-Unset-need_charset_alias-when-building-for-musl.patch \ 3 file://0001-Unset-need_charset_alias-when-building-for-musl.patch \
4 file://Fix-timestamping-and-continue-behaviour-with-ftp-pro.patch \
5 file://CVE-2016-4971.patch \
4 " 6 "
5 7
6SRC_URI[md5sum] = "f61d9011b99f824106a5d5a05dd0f63d" 8SRC_URI[md5sum] = "f61d9011b99f824106a5d5a05dd0f63d"