summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuj Mittal <anuj.mittal@intel.com>2020-02-05 12:39:05 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-02-21 09:44:05 +0000
commit496b5101b206902c67704de7c8f790f04845b2a8 (patch)
tree703c165856005242aa554e49c6507328452f8449
parent80df8a60bb890edf29e12d07092bf76633170fda (diff)
downloadpoky-496b5101b206902c67704de7c8f790f04845b2a8.tar.gz
cpio: fix CVE-2019-14866
(From OE-Core rev: ea0553398a2882a7a6e3c276dd3d81129a417a25) Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> (cherry picked from commit 3a9872c664cdc5c5a6ac712142ce1d28d6fcd6d1) Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/cpio/cpio-2.12/CVE-2019-14866.patch316
-rw-r--r--meta/recipes-extended/cpio/cpio_2.12.bb1
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 @@
1CVE: CVE-2019-14866
2Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/cpio.git/commit/?id=7554e3e42cd72f6f8304410c47fe6f8918e9bfd7]
3Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
4
5From a052401293e45a13cded5959b258204dae6d0af5 Mon Sep 17 00:00:00 2001
6From: Sergey Poznyakoff <gray@gnu.org>
7Date: Sun, 3 Nov 2019 23:59:39 +0200
8Subject: [PATCH] Fix CVE-2019-14866
9
10* src/copyout.c (to_ascii): Additional argument nul controls whether
11to add the terminating nul character.
12(field_width_error): Improve diagnostics: print the actual and the
13maximum 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
19success, 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
26diff --git a/src/copyout.c b/src/copyout.c
27index 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,
146diff --git a/src/extern.h b/src/extern.h
147index 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
188diff --git a/src/tar.c b/src/tar.c
189index 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--
3152.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
16SRC_URI[md5sum] = "fc207561a86b63862eea4b8300313e86" 17SRC_URI[md5sum] = "fc207561a86b63862eea4b8300313e86"