diff options
author | Anuj Mittal <anuj.mittal@intel.com> | 2020-02-05 12:39:05 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-02-11 23:05:12 +0000 |
commit | 8a398c5fab8594a6d985298dd796ab4e84c41ad9 (patch) | |
tree | bcc8ab0a1bb74bf932523fe73b9308d02063b416 /meta/recipes-extended | |
parent | d447876b4f68e9b3fd3b389dfc403ed831290a54 (diff) | |
download | poky-8a398c5fab8594a6d985298dd796ab4e84c41ad9.tar.gz |
cpio: fix CVE-2019-14866
(From OE-Core rev: c06d69e6dccb849e60847a33593fa20e192feea2)
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended')
-rw-r--r-- | meta/recipes-extended/cpio/cpio-2.12/CVE-2019-14866.patch | 316 | ||||
-rw-r--r-- | meta/recipes-extended/cpio/cpio_2.12.bb | 1 |
2 files changed, 317 insertions, 0 deletions
diff --git a/meta/recipes-extended/cpio/cpio-2.12/CVE-2019-14866.patch b/meta/recipes-extended/cpio/cpio-2.12/CVE-2019-14866.patch new file mode 100644 index 0000000000..5d587fc832 --- /dev/null +++ b/meta/recipes-extended/cpio/cpio-2.12/CVE-2019-14866.patch | |||
@@ -0,0 +1,316 @@ | |||
1 | CVE: CVE-2019-14866 | ||
2 | Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/cpio.git/commit/?id=7554e3e42cd72f6f8304410c47fe6f8918e9bfd7] | ||
3 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
4 | |||
5 | From a052401293e45a13cded5959b258204dae6d0af5 Mon Sep 17 00:00:00 2001 | ||
6 | From: Sergey Poznyakoff <gray@gnu.org> | ||
7 | Date: Sun, 3 Nov 2019 23:59:39 +0200 | ||
8 | Subject: [PATCH] Fix CVE-2019-14866 | ||
9 | |||
10 | * src/copyout.c (to_ascii): Additional argument nul controls whether | ||
11 | to add the terminating nul character. | ||
12 | (field_width_error): Improve diagnostics: print the actual and the | ||
13 | maximum allowed field value. | ||
14 | * src/extern.h (to_ascii, field_width_error): New prototypes. | ||
15 | * src/tar.c (to_oct): Remove. | ||
16 | (to_oct_or_error): New function. | ||
17 | (TO_OCT): New macro. | ||
18 | (write_out_tar_header): Use TO_OCT and to_ascii. Return 0 on | ||
19 | success, 1 on error. | ||
20 | --- | ||
21 | src/copyout.c | 49 ++++++++++++++++++++++-------------- | ||
22 | src/extern.h | 15 +++++++++-- | ||
23 | src/tar.c | 69 ++++++++++++++++++++++++--------------------------- | ||
24 | 3 files changed, 75 insertions(+), 58 deletions(-) | ||
25 | |||
26 | diff --git a/src/copyout.c b/src/copyout.c | ||
27 | index 1f0987a..1ae5477 100644 | ||
28 | --- a/src/copyout.c | ||
29 | +++ b/src/copyout.c | ||
30 | @@ -269,26 +269,32 @@ writeout_final_defers (int out_des) | ||
31 | so it should be moved to paxutils too. | ||
32 | Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */ | ||
33 | int | ||
34 | -to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase) | ||
35 | +to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase, bool nul) | ||
36 | { | ||
37 | static char codetab[] = "0123456789ABCDEF"; | ||
38 | - int i = digits; | ||
39 | - | ||
40 | - do | ||
41 | + | ||
42 | + if (nul) | ||
43 | + where[--digits] = 0; | ||
44 | + while (digits > 0) | ||
45 | { | ||
46 | - where[--i] = codetab[(v & ((1 << logbase) - 1))]; | ||
47 | + where[--digits] = codetab[(v & ((1 << logbase) - 1))]; | ||
48 | v >>= logbase; | ||
49 | } | ||
50 | - while (i); | ||
51 | |||
52 | return v != 0; | ||
53 | } | ||
54 | |||
55 | -static void | ||
56 | -field_width_error (const char *filename, const char *fieldname) | ||
57 | +void | ||
58 | +field_width_error (const char *filename, const char *fieldname, | ||
59 | + uintmax_t value, size_t width, bool nul) | ||
60 | { | ||
61 | - error (0, 0, _("%s: field width not sufficient for storing %s"), | ||
62 | - filename, fieldname); | ||
63 | + char valbuf[UINTMAX_STRSIZE_BOUND + 1]; | ||
64 | + char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; | ||
65 | + error (0, 0, _("%s: value %s %s out of allowed range 0..%s"), | ||
66 | + filename, fieldname, | ||
67 | + STRINGIFY_BIGINT (value, valbuf), | ||
68 | + STRINGIFY_BIGINT (MAX_VAL_WITH_DIGITS (width - nul, LG_8), | ||
69 | + maxbuf)); | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | @@ -303,7 +309,7 @@ to_ascii_or_warn (char *where, uintmax_t n, size_t digits, | ||
74 | unsigned logbase, | ||
75 | const char *filename, const char *fieldname) | ||
76 | { | ||
77 | - if (to_ascii (where, n, digits, logbase)) | ||
78 | + if (to_ascii (where, n, digits, logbase, false)) | ||
79 | field_width_warning (filename, fieldname); | ||
80 | } | ||
81 | |||
82 | @@ -312,9 +318,9 @@ to_ascii_or_error (char *where, uintmax_t n, size_t digits, | ||
83 | unsigned logbase, | ||
84 | const char *filename, const char *fieldname) | ||
85 | { | ||
86 | - if (to_ascii (where, n, digits, logbase)) | ||
87 | + if (to_ascii (where, n, digits, logbase, false)) | ||
88 | { | ||
89 | - field_width_error (filename, fieldname); | ||
90 | + field_width_error (filename, fieldname, n, digits, false); | ||
91 | return 1; | ||
92 | } | ||
93 | return 0; | ||
94 | @@ -371,7 +377,7 @@ write_out_new_ascii_header (const char *magic_string, | ||
95 | _("name size"))) | ||
96 | return 1; | ||
97 | p += 8; | ||
98 | - to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16); | ||
99 | + to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16, false); | ||
100 | |||
101 | tape_buffered_write (ascii_header, out_des, sizeof ascii_header); | ||
102 | |||
103 | @@ -388,7 +394,7 @@ write_out_old_ascii_header (dev_t dev, dev_t rdev, | ||
104 | char ascii_header[76]; | ||
105 | char *p = ascii_header; | ||
106 | |||
107 | - to_ascii (p, file_hdr->c_magic, 6, LG_8); | ||
108 | + to_ascii (p, file_hdr->c_magic, 6, LG_8, false); | ||
109 | p += 6; | ||
110 | to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number")); | ||
111 | p += 6; | ||
112 | @@ -492,7 +498,10 @@ write_out_binary_header (dev_t rdev, | ||
113 | short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF; | ||
114 | if (short_hdr.c_namesize != file_hdr->c_namesize) | ||
115 | { | ||
116 | - field_width_error (file_hdr->c_name, _("name size")); | ||
117 | + char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; | ||
118 | + error (0, 0, _("%s: value %s %s out of allowed range 0..%u"), | ||
119 | + file_hdr->c_name, _("name size"), | ||
120 | + STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFu); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | @@ -502,7 +511,10 @@ write_out_binary_header (dev_t rdev, | ||
125 | if (((off_t)short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1] | ||
126 | != file_hdr->c_filesize) | ||
127 | { | ||
128 | - field_width_error (file_hdr->c_name, _("file size")); | ||
129 | + char maxbuf[UINTMAX_STRSIZE_BOUND + 1]; | ||
130 | + error (0, 0, _("%s: value %s %s out of allowed range 0..%lu"), | ||
131 | + file_hdr->c_name, _("file size"), | ||
132 | + STRINGIFY_BIGINT (file_hdr->c_namesize, maxbuf), 0xFFFFFFFFlu); | ||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | @@ -552,8 +564,7 @@ write_out_header (struct cpio_file_stat *file_hdr, int out_des) | ||
137 | error (0, 0, _("%s: file name too long"), file_hdr->c_name); | ||
138 | return 1; | ||
139 | } | ||
140 | - write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */ | ||
141 | - return 0; | ||
142 | + return write_out_tar_header (file_hdr, out_des); | ||
143 | |||
144 | case arf_binary: | ||
145 | return write_out_binary_header (makedev (file_hdr->c_rdev_maj, | ||
146 | diff --git a/src/extern.h b/src/extern.h | ||
147 | index e27d662..f9ef56a 100644 | ||
148 | --- a/src/extern.h | ||
149 | +++ b/src/extern.h | ||
150 | @@ -117,6 +117,10 @@ void print_name_with_quoting (char *p); | ||
151 | /* copyout.c */ | ||
152 | int write_out_header (struct cpio_file_stat *file_hdr, int out_des); | ||
153 | void process_copy_out (void); | ||
154 | +int to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase, | ||
155 | + bool nul); | ||
156 | +void field_width_error (const char *filename, const char *fieldname, | ||
157 | + uintmax_t value, size_t width, bool nul); | ||
158 | |||
159 | /* copypass.c */ | ||
160 | void process_copy_pass (void); | ||
161 | @@ -145,7 +149,7 @@ int make_path (char *argpath, uid_t owner, gid_t group, | ||
162 | const char *verbose_fmt_string); | ||
163 | |||
164 | /* tar.c */ | ||
165 | -void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des); | ||
166 | +int write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des); | ||
167 | int null_block (long *block, int size); | ||
168 | void read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des); | ||
169 | int otoa (char *s, unsigned long *n); | ||
170 | @@ -204,9 +208,16 @@ void cpio_safer_name_suffix (char *name, bool link_target, | ||
171 | int cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir); | ||
172 | void change_dir (void); | ||
173 | |||
174 | -/* FIXME: These two defines should be defined in paxutils */ | ||
175 | +/* FIXME: The following three should be defined in paxutils */ | ||
176 | #define LG_8 3 | ||
177 | #define LG_16 4 | ||
178 | +/* The maximum uintmax_t value that can be represented with DIGITS digits, | ||
179 | + assuming that each digit is BITS_PER_DIGIT wide. */ | ||
180 | +#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \ | ||
181 | + ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \ | ||
182 | + ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \ | ||
183 | + : (uintmax_t) -1) | ||
184 | + | ||
185 | |||
186 | uintmax_t from_ascii (char const *where, size_t digs, unsigned logbase); | ||
187 | |||
188 | diff --git a/src/tar.c b/src/tar.c | ||
189 | index a2ce171..ef58027 100644 | ||
190 | --- a/src/tar.c | ||
191 | +++ b/src/tar.c | ||
192 | @@ -79,36 +79,17 @@ stash_tar_filename (char *prefix, char *filename) | ||
193 | return hold_tar_filename; | ||
194 | } | ||
195 | |||
196 | -/* Convert a number into a string of octal digits. | ||
197 | - Convert long VALUE into a DIGITS-digit field at WHERE, | ||
198 | - including a trailing space and room for a NUL. DIGITS==3 means | ||
199 | - 1 digit, a space, and room for a NUL. | ||
200 | - | ||
201 | - We assume the trailing NUL is already there and don't fill it in. | ||
202 | - This fact is used by start_header and finish_header, so don't change it! | ||
203 | - | ||
204 | - This is be equivalent to: | ||
205 | - sprintf (where, "%*lo ", digits - 2, value); | ||
206 | - except that sprintf fills in the trailing NUL and we don't. */ | ||
207 | - | ||
208 | -static void | ||
209 | -to_oct (register long value, register int digits, register char *where) | ||
210 | +static int | ||
211 | +to_oct_or_error (uintmax_t value, size_t digits, char *where, char const *field, | ||
212 | + char const *file) | ||
213 | { | ||
214 | - --digits; /* Leave the trailing NUL slot alone. */ | ||
215 | - | ||
216 | - /* Produce the digits -- at least one. */ | ||
217 | - do | ||
218 | + if (to_ascii (where, value, digits, LG_8, true)) | ||
219 | { | ||
220 | - where[--digits] = '0' + (char) (value & 7); /* One octal digit. */ | ||
221 | - value >>= 3; | ||
222 | + field_width_error (file, field, value, digits, true); | ||
223 | + return 1; | ||
224 | } | ||
225 | - while (digits > 0 && value != 0); | ||
226 | - | ||
227 | - /* Add leading zeroes, if necessary. */ | ||
228 | - while (digits > 0) | ||
229 | - where[--digits] = '0'; | ||
230 | + return 0; | ||
231 | } | ||
232 | - | ||
233 | |||
234 | |||
235 | /* Compute and return a checksum for TAR_HDR, | ||
236 | @@ -134,10 +115,22 @@ tar_checksum (struct tar_header *tar_hdr) | ||
237 | return sum; | ||
238 | } | ||
239 | |||
240 | +#define TO_OCT(file_hdr, c_fld, digits, tar_hdr, tar_field) \ | ||
241 | + do \ | ||
242 | + { \ | ||
243 | + if (to_oct_or_error (file_hdr -> c_fld, \ | ||
244 | + digits, \ | ||
245 | + tar_hdr -> tar_field, \ | ||
246 | + #tar_field, \ | ||
247 | + file_hdr->c_name)) \ | ||
248 | + return 1; \ | ||
249 | + } \ | ||
250 | + while (0) | ||
251 | + | ||
252 | /* Write out header FILE_HDR, including the file name, to file | ||
253 | descriptor OUT_DES. */ | ||
254 | |||
255 | -void | ||
256 | +int | ||
257 | write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) | ||
258 | { | ||
259 | int name_len; | ||
260 | @@ -166,11 +159,11 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) | ||
261 | |||
262 | /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal | ||
263 | digits */ | ||
264 | - to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode); | ||
265 | - to_oct (file_hdr->c_uid, 8, tar_hdr->uid); | ||
266 | - to_oct (file_hdr->c_gid, 8, tar_hdr->gid); | ||
267 | - to_oct (file_hdr->c_filesize, 12, tar_hdr->size); | ||
268 | - to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime); | ||
269 | + TO_OCT (file_hdr, c_mode & MODE_ALL, 8, tar_hdr, mode); | ||
270 | + TO_OCT (file_hdr, c_uid, 8, tar_hdr, uid); | ||
271 | + TO_OCT (file_hdr, c_gid, 8, tar_hdr, gid); | ||
272 | + TO_OCT (file_hdr, c_filesize, 12, tar_hdr, size); | ||
273 | + TO_OCT (file_hdr, c_mtime, 12, tar_hdr, mtime); | ||
274 | |||
275 | switch (file_hdr->c_mode & CP_IFMT) | ||
276 | { | ||
277 | @@ -182,7 +175,7 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) | ||
278 | strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, | ||
279 | TARLINKNAMESIZE); | ||
280 | tar_hdr->typeflag = LNKTYPE; | ||
281 | - to_oct (0, 12, tar_hdr->size); | ||
282 | + to_ascii (tar_hdr->size, 0, 12, LG_8, true); | ||
283 | } | ||
284 | else | ||
285 | tar_hdr->typeflag = REGTYPE; | ||
286 | @@ -208,7 +201,7 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) | ||
287 | than TARLINKNAMESIZE. */ | ||
288 | strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, | ||
289 | TARLINKNAMESIZE); | ||
290 | - to_oct (0, 12, tar_hdr->size); | ||
291 | + to_ascii (tar_hdr->size, 0, 12, LG_8, true); | ||
292 | break; | ||
293 | #endif /* CP_IFLNK */ | ||
294 | } | ||
295 | @@ -227,13 +220,15 @@ write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) | ||
296 | if (name) | ||
297 | strcpy (tar_hdr->gname, name); | ||
298 | |||
299 | - to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor); | ||
300 | - to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor); | ||
301 | + TO_OCT (file_hdr, c_rdev_maj, 8, tar_hdr, devmajor); | ||
302 | + TO_OCT (file_hdr, c_rdev_min, 8, tar_hdr, devminor); | ||
303 | } | ||
304 | |||
305 | - to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum); | ||
306 | + to_ascii (tar_hdr->chksum, tar_checksum (tar_hdr), 8, LG_8, true); | ||
307 | |||
308 | tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE); | ||
309 | + | ||
310 | + return 0; | ||
311 | } | ||
312 | |||
313 | /* Return nonzero iff all the bytes in BLOCK are NUL. | ||
314 | -- | ||
315 | 2.24.1 | ||
316 | |||
diff --git a/meta/recipes-extended/cpio/cpio_2.12.bb b/meta/recipes-extended/cpio/cpio_2.12.bb index 3713bf0b1f..5abe494ebc 100644 --- a/meta/recipes-extended/cpio/cpio_2.12.bb +++ b/meta/recipes-extended/cpio/cpio_2.12.bb | |||
@@ -11,6 +11,7 @@ SRC_URI = "${GNU_MIRROR}/cpio/cpio-${PV}.tar.gz \ | |||
11 | file://0001-Fix-CVE-2015-1197.patch \ | 11 | file://0001-Fix-CVE-2015-1197.patch \ |
12 | file://0001-CVE-2016-2037-1-byte-out-of-bounds-write.patch \ | 12 | file://0001-CVE-2016-2037-1-byte-out-of-bounds-write.patch \ |
13 | file://0001-Fix-segfault-with-append.patch \ | 13 | file://0001-Fix-segfault-with-append.patch \ |
14 | file://CVE-2019-14866.patch \ | ||
14 | " | 15 | " |
15 | 16 | ||
16 | SRC_URI[md5sum] = "fc207561a86b63862eea4b8300313e86" | 17 | SRC_URI[md5sum] = "fc207561a86b63862eea4b8300313e86" |