summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorChong Lu <Chong.Lu@windriver.com>2015-01-22 17:28:34 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-02-06 14:56:07 +0000
commit46e8377c42030eb04972940cd022a8d214d477c7 (patch)
tree4bf54419eb27d1e8eb1c715ed1f55ab3d2d4b2b2 /meta
parent148b7d20d40588e3dd34fddaec850b7238c580ce (diff)
downloadpoky-46e8377c42030eb04972940cd022a8d214d477c7.tar.gz
file: CVE-2014-9620 and CVE-2014-9621
CVE-2014-9620: Limit the number of ELF notes processed - DoS CVE-2014-9621: Limit string printing to 100 chars - DoS The patch comes from: https://github.com/file/file/commit/6ce24f35cd4a43c4bdd249e8e0c4952c1f8eac67 https://github.com/file/file/commit/0056ec32255de1de973574b0300161a1568767d6 https://github.com/file/file/commit/09e41625c999a2e5b51e1092f0ef2432a99b5c33 https://github.com/file/file/commit/af444af0738468393f40f9d2261b1ea10fc4b2ba https://github.com/file/file/commit/68bd8433c7e11a8dbe100deefdfac69138ee7cd9 https://github.com/file/file/commit/dddd3cdb95210a765dd90f7d722cb8b5534daee7 https://github.com/file/file/commit/445c8fb0ebff85195be94cd9f7e1df89cade5c7f https://github.com/file/file/commit/ce90e05774dd77d86cfc8dfa6da57b32816841c4 https://github.com/file/file/commit/65437cee25199dbd385fb35901bc0011e164276c [YOCTO #7178] (From OE-Core rev: ee78555fe54e98c6296566b5e701ef268d77db61) Signed-off-by: Chong Lu <Chong.Lu@windriver.com> [sgw - Fixed magic.h.in to match magic.h] Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch1359
-rw-r--r--meta/recipes-devtools/file/file_5.16.bb1
2 files changed, 1360 insertions, 0 deletions
diff --git a/meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch b/meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch
new file mode 100644
index 0000000000..af02b995b7
--- /dev/null
+++ b/meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch
@@ -0,0 +1,1359 @@
1file: CVE-2014-9620 and CVE-2014-9621
2
3The patch comes from:
4https://github.com/file/file/commit/6ce24f35cd4a43c4bdd249e8e0c4952c1f8eac67
5https://github.com/file/file/commit/0056ec32255de1de973574b0300161a1568767d6
6https://github.com/file/file/commit/09e41625c999a2e5b51e1092f0ef2432a99b5c33
7https://github.com/file/file/commit/af444af0738468393f40f9d2261b1ea10fc4b2ba
8https://github.com/file/file/commit/68bd8433c7e11a8dbe100deefdfac69138ee7cd9
9https://github.com/file/file/commit/dddd3cdb95210a765dd90f7d722cb8b5534daee7
10https://github.com/file/file/commit/445c8fb0ebff85195be94cd9f7e1df89cade5c7f
11https://github.com/file/file/commit/ce90e05774dd77d86cfc8dfa6da57b32816841c4
12https://github.com/file/file/commit/65437cee25199dbd385fb35901bc0011e164276c
13
14Upstream-Status: Backport
15
16Signed-off-by: Chong Lu <Chong.Lu@windriver.com>
17---
18 src/apprentice.c | 5 +
19 src/ascmagic.c | 3 +-
20 src/elfclass.h | 34 ++--
21 src/file.c | 58 ++++++-
22 src/file.h | 20 ++-
23 src/file_opts.h | 6 +
24 src/funcs.c | 42 ++++-
25 src/magic.c | 50 ++++++
26 src/magic.h | 9 ++
27 src/magic.h.in | 4 +
28 src/readelf.c | 467 +++++++++++++++++++++++++++++++++---------------------
29 src/softmagic.c | 70 ++++----
30 12 files changed, 541 insertions(+), 227 deletions(-)
31
32Index: file-5.16/src/apprentice.c
33===================================================================
34--- file-5.16.orig/src/apprentice.c
35+++ file-5.16/src/apprentice.c
36@@ -494,6 +494,11 @@ file_ms_alloc(int flags)
37 ms->mlist[i] = NULL;
38 ms->file = "unknown";
39 ms->line = 0;
40+ ms->indir_max = FILE_INDIR_MAX;
41+ ms->name_max = FILE_NAME_MAX;
42+ ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
43+ ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
44+ ms->elf_notes_max = FILE_ELF_NOTES_MAX;
45 return ms;
46 free:
47 free(ms);
48Index: file-5.16/src/ascmagic.c
49===================================================================
50--- file-5.16.orig/src/ascmagic.c
51+++ file-5.16/src/ascmagic.c
52@@ -147,7 +147,8 @@ file_ascmagic_with_encoding(struct magic
53 == NULL)
54 goto done;
55 if ((rv = file_softmagic(ms, utf8_buf,
56- (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0)
57+ (size_t)(utf8_end - utf8_buf), 0, NULL,
58+ TEXTTEST, text)) == 0)
59 rv = -1;
60 }
61
62Index: file-5.16/src/elfclass.h
63===================================================================
64--- file-5.16.orig/src/elfclass.h
65+++ file-5.16/src/elfclass.h
66@@ -32,39 +32,51 @@
67 swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
68
69 type = elf_getu16(swap, elfhdr.e_type);
70+ notecount = ms->elf_notes_max;
71 switch (type) {
72 #ifdef ELFCORE
73 case ET_CORE:
74+ phnum = elf_getu16(swap, elfhdr.e_phnum);
75+ if (phnum > ms->elf_phnum_max)
76+ return toomany(ms, "program headers", phnum);
77 flags |= FLAGS_IS_CORE;
78 if (dophn_core(ms, clazz, swap, fd,
79- (off_t)elf_getu(swap, elfhdr.e_phoff),
80- elf_getu16(swap, elfhdr.e_phnum),
81+ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
82 (size_t)elf_getu16(swap, elfhdr.e_phentsize),
83- fsize, &flags) == -1)
84+ fsize, &flags, &notecount) == -1)
85 return -1;
86 break;
87 #endif
88 case ET_EXEC:
89 case ET_DYN:
90+ phnum = elf_getu16(swap, elfhdr.e_phnum);
91+ if (phnum > ms->elf_phnum_max)
92+ return toomany(ms, "program", phnum);
93+ shnum = elf_getu16(swap, elfhdr.e_shnum);
94+ if (shnum > ms->elf_shnum_max)
95+ return toomany(ms, "section", shnum);
96 if (dophn_exec(ms, clazz, swap, fd,
97- (off_t)elf_getu(swap, elfhdr.e_phoff),
98- elf_getu16(swap, elfhdr.e_phnum),
99+ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
100 (size_t)elf_getu16(swap, elfhdr.e_phentsize),
101- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
102- == -1)
103+ fsize, shnum, &flags, &notecount) == -1)
104 return -1;
105 /*FALLTHROUGH*/
106 case ET_REL:
107+ shnum = elf_getu16(swap, elfhdr.e_shnum);
108+ if (shnum > ms->elf_shnum_max)
109+ return toomany(ms, "section headers", shnum);
110 if (doshn(ms, clazz, swap, fd,
111- (off_t)elf_getu(swap, elfhdr.e_shoff),
112- elf_getu16(swap, elfhdr.e_shnum),
113+ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
114 (size_t)elf_getu16(swap, elfhdr.e_shentsize),
115- fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
116- (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
117+ fsize, elf_getu16(swap, elfhdr.e_machine),
118+ (int)elf_getu16(swap, elfhdr.e_shstrndx),
119+ &flags, &notecount) == -1)
120 return -1;
121 break;
122
123 default:
124 break;
125 }
126+ if (notecount == 0)
127+ return toomany(ms, "notes", ms->elf_notes_max);
128 return 1;
129Index: file-5.16/src/file.c
130===================================================================
131--- file-5.16.orig/src/file.c
132+++ file-5.16/src/file.c
133@@ -101,7 +101,7 @@ private const struct option long_options
134 #undef OPT_LONGONLY
135 {0, 0, NULL, 0}
136 };
137-#define OPTSTRING "bcCde:f:F:hiklLm:nNprsvz0"
138+#define OPTSTRING "bcCde:f:F:hiklLm:nNpP:rsvz0"
139
140 private const struct {
141 const char *name;
142@@ -119,6 +119,18 @@ private const struct {
143 { "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
144 };
145
146+private struct {
147+ const char *name;
148+ int tag;
149+ size_t value;
150+} pm[] = {
151+ { "indir", MAGIC_PARAM_INDIR_MAX, 0 },
152+ { "name", MAGIC_PARAM_NAME_MAX, 0 },
153+ { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
154+ { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
155+ { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
156+};
157+
158 private char *progname; /* used throughout */
159
160 private void usage(void);
161@@ -128,6 +140,8 @@ private void help(void);
162 private int unwrap(struct magic_set *, const char *);
163 private int process(struct magic_set *ms, const char *, int);
164 private struct magic_set *load(const char *, int);
165+private void setparam(const char *);
166+private void applyparam(magic_t);
167
168
169 /*
170@@ -240,6 +254,9 @@ main(int argc, char *argv[])
171 flags |= MAGIC_PRESERVE_ATIME;
172 break;
173 #endif
174+ case 'P':
175+ setparam(optarg);
176+ break;
177 case 'r':
178 flags |= MAGIC_RAW;
179 break;
180@@ -295,6 +312,8 @@ main(int argc, char *argv[])
181 strerror(errno));
182 return 1;
183 }
184+
185+
186 switch(action) {
187 case FILE_CHECK:
188 c = magic_check(magic, magicfile);
189@@ -318,7 +337,7 @@ main(int argc, char *argv[])
190 if (magic == NULL)
191 if ((magic = load(magicfile, flags)) == NULL)
192 return 1;
193- break;
194+ applyparam(magic);
195 }
196
197 if (optind == argc) {
198@@ -348,6 +367,41 @@ main(int argc, char *argv[])
199 return e;
200 }
201
202+private void
203+applyparam(magic_t magic)
204+{
205+ size_t i;
206+
207+ for (i = 0; i < __arraycount(pm); i++) {
208+ if (pm[i].value == 0)
209+ continue;
210+ if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) {
211+ (void)fprintf(stderr, "%s: Can't set %s %s\n", progname,
212+ pm[i].name, strerror(errno));
213+ exit(1);
214+ }
215+ }
216+}
217+
218+private void
219+setparam(const char *p)
220+{
221+ size_t i;
222+ char *s;
223+
224+ if ((s = strchr(p, '=')) == NULL)
225+ goto badparm;
226+
227+ for (i = 0; i < __arraycount(pm); i++) {
228+ if (strncmp(p, pm[i].name, s - p) != 0)
229+ continue;
230+ pm[i].value = atoi(s + 1);
231+ return;
232+ }
233+badparm:
234+ (void)fprintf(stderr, "%s: Unknown param %s\n", progname, p);
235+ exit(1);
236+}
237
238 private struct magic_set *
239 /*ARGSUSED*/
240Index: file-5.16/src/file.h
241===================================================================
242--- file-5.16.orig/src/file.h
243+++ file-5.16/src/file.h
244@@ -400,6 +400,16 @@ struct magic_set {
245 /* FIXME: Make the string dynamically allocated so that e.g.
246 strings matched in files can be longer than MAXstring */
247 union VALUETYPE ms_value; /* either number or string */
248+ uint16_t indir_max;
249+ uint16_t name_max;
250+ uint16_t elf_shnum_max;
251+ uint16_t elf_phnum_max;
252+ uint16_t elf_notes_max;
253+#define FILE_INDIR_MAX 15
254+#define FILE_NAME_MAX 30
255+#define FILE_ELF_SHNUM_MAX 32768
256+#define FILE_ELF_PHNUM_MAX 128
257+#define FILE_ELF_NOTES_MAX 256
258 };
259
260 /* Type for Unicode characters */
261@@ -438,7 +448,7 @@ protected int file_encoding(struct magic
262 unichar **, size_t *, const char **, const char **, const char **);
263 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
264 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
265- int, int);
266+ uint16_t, uint16_t *, int, int);
267 protected int file_apprentice(struct magic_set *, const char *, int);
268 protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
269 protected uint64_t file_signextend(struct magic_set *, struct magic *,
270@@ -468,6 +478,14 @@ protected int file_os2_apptype(struct ma
271 #endif /* __EMX__ */
272
273
274+typedef struct {
275+ char *buf;
276+ uint32_t offset;
277+} file_pushbuf_t;
278+
279+protected file_pushbuf_t *file_push_buffer(struct magic_set *);
280+protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
281+
282 #ifndef COMPILE_ONLY
283 extern const char *file_names[];
284 extern const size_t file_nnames;
285Index: file-5.16/src/file_opts.h
286===================================================================
287--- file-5.16.orig/src/file_opts.h
288+++ file-5.16/src/file_opts.h
289@@ -43,6 +43,12 @@ OPT('0', "print0", 0, " te
290 #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
291 OPT('p', "preserve-date", 0, " preserve access times on files\n")
292 #endif
293+OPT('P', "parameter", 0, " set file engine parameter limits\n"
294+ " indir 15 recursion limit for indirection\n"
295+ " name 30 use limit for name/use magic\n"
296+ " elf_notes 256 max ELF notes processed\n"
297+ " elf_phnum 128 max ELF prog sections processed\n"
298+ " elf_shnum 32768 max ELF sections processed\n")
299 OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n")
300 OPT('s', "special-files", 0, " treat special (block/char devices) files as\n"
301 " ordinary ones\n")
302Index: file-5.16/src/funcs.c
303===================================================================
304--- file-5.16.orig/src/funcs.c
305+++ file-5.16/src/funcs.c
306@@ -226,7 +226,7 @@ file_buffer(struct magic_set *ms, int fd
307
308 /* try soft magic tests */
309 if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
310- if ((m = file_softmagic(ms, ubuf, nb, BINTEST,
311+ if ((m = file_softmagic(ms, ubuf, nb, 0, NULL, BINTEST,
312 looks_text)) != 0) {
313 if ((ms->flags & MAGIC_DEBUG) != 0)
314 (void)fprintf(stderr, "softmagic %d\n", m);
315@@ -459,3 +459,43 @@ file_replace(struct magic_set *ms, const
316 return nm;
317 }
318 }
319+
320+protected file_pushbuf_t *
321+file_push_buffer(struct magic_set *ms)
322+{
323+ file_pushbuf_t *pb;
324+
325+ if (ms->event_flags & EVENT_HAD_ERR)
326+ return NULL;
327+
328+ if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
329+ return NULL;
330+
331+ pb->buf = ms->o.buf;
332+ pb->offset = ms->offset;
333+
334+ ms->o.buf = NULL;
335+ ms->offset = 0;
336+
337+ return pb;
338+}
339+
340+protected char *
341+file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
342+{
343+ char *rbuf;
344+
345+ if (ms->event_flags & EVENT_HAD_ERR) {
346+ free(pb->buf);
347+ free(pb);
348+ return NULL;
349+ }
350+
351+ rbuf = ms->o.buf;
352+
353+ ms->o.buf = pb->buf;
354+ ms->offset = pb->offset;
355+
356+ free(pb);
357+ return rbuf;
358+}
359Index: file-5.16/src/magic.c
360===================================================================
361--- file-5.16.orig/src/magic.c
362+++ file-5.16/src/magic.c
363@@ -490,3 +490,53 @@ magic_version(void)
364 {
365 return MAGIC_VERSION;
366 }
367+
368+public int
369+magic_setparam(struct magic_set *ms, int param, const void *val)
370+{
371+ switch (param) {
372+ case MAGIC_PARAM_INDIR_MAX:
373+ ms->indir_max = *(const size_t *)val;
374+ return 0;
375+ case MAGIC_PARAM_NAME_MAX:
376+ ms->name_max = *(const size_t *)val;
377+ return 0;
378+ case MAGIC_PARAM_ELF_PHNUM_MAX:
379+ ms->elf_phnum_max = *(const size_t *)val;
380+ return 0;
381+ case MAGIC_PARAM_ELF_SHNUM_MAX:
382+ ms->elf_shnum_max = *(const size_t *)val;
383+ return 0;
384+ case MAGIC_PARAM_ELF_NOTES_MAX:
385+ ms->elf_notes_max = *(const size_t *)val;
386+ return 0;
387+ default:
388+ errno = EINVAL;
389+ return -1;
390+ }
391+}
392+
393+public int
394+magic_getparam(struct magic_set *ms, int param, void *val)
395+{
396+ switch (param) {
397+ case MAGIC_PARAM_INDIR_MAX:
398+ *(size_t *)val = ms->indir_max;
399+ return 0;
400+ case MAGIC_PARAM_NAME_MAX:
401+ *(size_t *)val = ms->name_max;
402+ return 0;
403+ case MAGIC_PARAM_ELF_PHNUM_MAX:
404+ *(size_t *)val = ms->elf_phnum_max;
405+ return 0;
406+ case MAGIC_PARAM_ELF_SHNUM_MAX:
407+ *(size_t *)val = ms->elf_shnum_max;
408+ return 0;
409+ case MAGIC_PARAM_ELF_NOTES_MAX:
410+ *(size_t *)val = ms->elf_notes_max;
411+ return 0;
412+ default:
413+ errno = EINVAL;
414+ return -1;
415+ }
416+}
417Index: file-5.16/src/magic.h
418===================================================================
419--- file-5.16.orig/src/magic.h
420+++ file-5.16/src/magic.h
421@@ -101,6 +101,15 @@ int magic_check(magic_t, const char *);
422 int magic_list(magic_t, const char *);
423 int magic_errno(magic_t);
424
425+#define MAGIC_PARAM_INDIR_MAX 0
426+#define MAGIC_PARAM_NAME_MAX 1
427+#define MAGIC_PARAM_ELF_PHNUM_MAX 2
428+#define MAGIC_PARAM_ELF_SHNUM_MAX 3
429+#define MAGIC_PARAM_ELF_NOTES_MAX 4
430+
431+int magic_setparam(magic_t, int, const void *);
432+int magic_getparam(magic_t, int, void *);
433+
434 #ifdef __cplusplus
435 };
436 #endif
437Index: file-5.16/src/magic.h.in
438===================================================================
439--- file-5.16.orig/src/magic.h.in
440+++ file-5.16/src/magic.h.in
441@@ -101,6 +101,15 @@ int magic_check(magic_t, const char *);
442 int magic_list(magic_t, const char *);
443 int magic_errno(magic_t);
444
445+#define MAGIC_PARAM_INDIR_MAX 0
446+#define MAGIC_PARAM_NAME_MAX 1
447+#define MAGIC_PARAM_ELF_PHNUM_MAX 2
448+#define MAGIC_PARAM_ELF_SHNUM_MAX 3
449+#define MAGIC_PARAM_ELF_NOTES_MAX 4
450+
451+int magic_setparam(magic_t, int, const void *);
452+int magic_getparam(magic_t, int, void *);
453+
454 #ifdef __cplusplus
455 };
456 #endif
457Index: file-5.16/src/readelf.c
458===================================================================
459--- file-5.16.orig/src/readelf.c
460+++ file-5.16/src/readelf.c
461@@ -43,14 +43,14 @@ FILE_RCSID("@(#)$File: readelf.c,v 1.99
462
463 #ifdef ELFCORE
464 private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
465- off_t, int *);
466+ off_t, int *, uint16_t *);
467 #endif
468 private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
469- off_t, int *, int);
470+ off_t, int, int *, uint16_t *);
471 private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
472- off_t, int *, int, int);
473+ off_t, int, int, int *, uint16_t *);
474 private size_t donote(struct magic_set *, void *, size_t, size_t, int,
475- int, size_t, int *);
476+ int, size_t, int *, uint16_t *);
477
478 #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
479
480@@ -60,6 +60,19 @@ private uint16_t getu16(int, uint16_t);
481 private uint32_t getu32(int, uint32_t);
482 private uint64_t getu64(int, uint64_t);
483
484+#define MAX_PHNUM 128
485+#define MAX_SHNUM 32768
486+#define SIZE_UNKNOWN ((off_t)-1)
487+
488+private int
489+toomany(struct magic_set *ms, const char *name, uint16_t num)
490+{
491+ if (file_printf(ms, ", too many %s (%u)", name, num
492+ ) == -1)
493+ return -1;
494+ return 0;
495+}
496+
497 private uint16_t
498 getu16(int swap, uint16_t value)
499 {
500@@ -280,15 +293,19 @@ private const char os_style_names[][8] =
501 "NetBSD",
502 };
503
504-#define FLAGS_DID_CORE 0x01
505-#define FLAGS_DID_NOTE 0x02
506-#define FLAGS_DID_BUILD_ID 0x04
507-#define FLAGS_DID_CORE_STYLE 0x08
508-#define FLAGS_IS_CORE 0x10
509+#define FLAGS_DID_CORE 0x001
510+#define FLAGS_DID_OS_NOTE 0x002
511+#define FLAGS_DID_BUILD_ID 0x004
512+#define FLAGS_DID_CORE_STYLE 0x008
513+#define FLAGS_DID_NETBSD_PAX 0x010
514+#define FLAGS_DID_NETBSD_MARCH 0x020
515+#define FLAGS_DID_NETBSD_CMODEL 0x040
516+#define FLAGS_DID_NETBSD_UNKNOWN 0x080
517+#define FLAGS_IS_CORE 0x100
518
519 private int
520 dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
521- int num, size_t size, off_t fsize, int *flags)
522+ int num, size_t size, off_t fsize, int *flags, uint16_t *notecount)
523 {
524 Elf32_Phdr ph32;
525 Elf64_Phdr ph64;
526@@ -306,13 +323,13 @@ dophn_core(struct magic_set *ms, int cla
527 * Loop through all the program headers.
528 */
529 for ( ; num; num--) {
530- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
531+ if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
532 file_badread(ms);
533 return -1;
534 }
535 off += size;
536
537- if (xph_offset > fsize) {
538+ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
539 /* Perhaps warn here */
540 continue;
541 }
542@@ -334,7 +351,7 @@ dophn_core(struct magic_set *ms, int cla
543 if (offset >= (size_t)bufsize)
544 break;
545 offset = donote(ms, nbuf, offset, (size_t)bufsize,
546- clazz, swap, 4, flags);
547+ clazz, swap, 4, flags, notecount);
548 if (offset == 0)
549 break;
550
551@@ -464,125 +481,127 @@ do_note_freebsd_version(struct magic_set
552 }
553 }
554
555-private size_t
556-donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
557- int clazz, int swap, size_t align, int *flags)
558+private int
559+do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
560+ int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
561+ size_t noff, size_t doff, int *flags)
562 {
563- Elf32_Nhdr nh32;
564- Elf64_Nhdr nh64;
565- size_t noff, doff;
566-#ifdef ELFCORE
567- int os_style = -1;
568-#endif
569- uint32_t namesz, descsz;
570- unsigned char *nbuf = CAST(unsigned char *, vbuf);
571-
572- (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
573- offset += xnh_sizeof;
574-
575- namesz = xnh_namesz;
576- descsz = xnh_descsz;
577- if ((namesz == 0) && (descsz == 0)) {
578- /*
579- * We're out of note headers.
580- */
581- return (offset >= size) ? offset : size;
582- }
583-
584- if (namesz & 0x80000000) {
585- (void)file_printf(ms, ", bad note name size 0x%lx",
586- (unsigned long)namesz);
587- return offset;
588- }
589-
590- if (descsz & 0x80000000) {
591- (void)file_printf(ms, ", bad note description size 0x%lx",
592- (unsigned long)descsz);
593- return offset;
594- }
595-
596-
597- noff = offset;
598- doff = ELF_ALIGN(offset + namesz);
599-
600- if (offset + namesz > size) {
601- /*
602- * We're past the end of the buffer.
603- */
604- return doff;
605- }
606-
607- offset = ELF_ALIGN(doff + descsz);
608- if (doff + descsz > size) {
609- /*
610- * We're past the end of the buffer.
611- */
612- return (offset >= size) ? offset : size;
613+ if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
614+ type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
615+ uint8_t desc[20];
616+ uint32_t i;
617+ *flags |= FLAGS_DID_BUILD_ID;
618+ if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
619+ "sha1") == -1)
620+ return 1;
621+ (void)memcpy(desc, &nbuf[doff], descsz);
622+ for (i = 0; i < descsz; i++)
623+ if (file_printf(ms, "%02x", desc[i]) == -1)
624+ return 1;
625+ return 1;
626 }
627-
628- if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) ==
629- (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
630- goto core;
631-
632+ return 0;
633+}
634+
635+private int
636+do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
637+ int swap, uint32_t namesz, uint32_t descsz,
638+ size_t noff, size_t doff, int *flags)
639+{
640 if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
641- xnh_type == NT_GNU_VERSION && descsz == 2) {
642+ type == NT_GNU_VERSION && descsz == 2) {
643+ *flags |= FLAGS_DID_OS_NOTE;
644 file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
645+ return 1;
646 }
647+
648 if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
649- xnh_type == NT_GNU_VERSION && descsz == 16) {
650+ type == NT_GNU_VERSION && descsz == 16) {
651 uint32_t desc[4];
652 (void)memcpy(desc, &nbuf[doff], sizeof(desc));
653
654+ *flags |= FLAGS_DID_OS_NOTE;
655 if (file_printf(ms, ", for GNU/") == -1)
656- return size;
657+ return 1;
658 switch (elf_getu32(swap, desc[0])) {
659 case GNU_OS_LINUX:
660 if (file_printf(ms, "Linux") == -1)
661- return size;
662+ return 1;
663 break;
664 case GNU_OS_HURD:
665 if (file_printf(ms, "Hurd") == -1)
666- return size;
667+ return 1;
668 break;
669 case GNU_OS_SOLARIS:
670 if (file_printf(ms, "Solaris") == -1)
671- return size;
672+ return 1;
673 break;
674 case GNU_OS_KFREEBSD:
675 if (file_printf(ms, "kFreeBSD") == -1)
676- return size;
677+ return 1;
678 break;
679 case GNU_OS_KNETBSD:
680 if (file_printf(ms, "kNetBSD") == -1)
681- return size;
682+ return 1;
683 break;
684 default:
685 if (file_printf(ms, "<unknown>") == -1)
686- return size;
687+ return 1;
688 }
689 if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
690 elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
691- return size;
692- *flags |= FLAGS_DID_NOTE;
693- return size;
694+ return 1;
695+ return 1;
696 }
697
698- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
699- xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
700- uint8_t desc[20];
701- uint32_t i;
702- if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
703- "sha1") == -1)
704- return size;
705- (void)memcpy(desc, &nbuf[doff], descsz);
706- for (i = 0; i < descsz; i++)
707- if (file_printf(ms, "%02x", desc[i]) == -1)
708- return size;
709- *flags |= FLAGS_DID_BUILD_ID;
710+ if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
711+ if (type == NT_NETBSD_VERSION && descsz == 4) {
712+ *flags |= FLAGS_DID_OS_NOTE;
713+ do_note_netbsd_version(ms, swap, &nbuf[doff]);
714+ return 1;
715+ }
716+ }
717+
718+ if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
719+ if (type == NT_FREEBSD_VERSION && descsz == 4) {
720+ *flags |= FLAGS_DID_OS_NOTE;
721+ do_note_freebsd_version(ms, swap, &nbuf[doff]);
722+ return 1;
723+ }
724+ }
725+
726+ if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
727+ type == NT_OPENBSD_VERSION && descsz == 4) {
728+ *flags |= FLAGS_DID_OS_NOTE;
729+ if (file_printf(ms, ", for OpenBSD") == -1)
730+ return 1;
731+ /* Content of note is always 0 */
732+ return 1;
733+ }
734+
735+ if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
736+ type == NT_DRAGONFLY_VERSION && descsz == 4) {
737+ uint32_t desc;
738+ *flags |= FLAGS_DID_OS_NOTE;
739+ if (file_printf(ms, ", for DragonFly") == -1)
740+ return 1;
741+ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
742+ desc = elf_getu32(swap, desc);
743+ if (file_printf(ms, " %d.%d.%d", desc / 100000,
744+ desc / 10000 % 10, desc % 10000) == -1)
745+ return 1;
746+ return 1;
747 }
748+ return 0;
749+}
750
751+private int
752+do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
753+ int swap, uint32_t namesz, uint32_t descsz,
754+ size_t noff, size_t doff, int *flags)
755+{
756 if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
757- xnh_type == NT_NETBSD_PAX && descsz == 4) {
758+ type == NT_NETBSD_PAX && descsz == 4) {
759 static const char *pax[] = {
760 "+mprotect",
761 "-mprotect",
762@@ -595,80 +614,32 @@ donote(struct magic_set *ms, void *vbuf,
763 size_t i;
764 int did = 0;
765
766+ *flags |= FLAGS_DID_NETBSD_PAX;
767 (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
768 desc = elf_getu32(swap, desc);
769
770 if (desc && file_printf(ms, ", PaX: ") == -1)
771- return size;
772+ return 1;
773
774 for (i = 0; i < __arraycount(pax); i++) {
775 if (((1 << i) & desc) == 0)
776 continue;
777 if (file_printf(ms, "%s%s", did++ ? "," : "",
778 pax[i]) == -1)
779- return size;
780- }
781- }
782-
783- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
784- switch (xnh_type) {
785- case NT_NETBSD_VERSION:
786- if (descsz == 4) {
787- do_note_netbsd_version(ms, swap, &nbuf[doff]);
788- *flags |= FLAGS_DID_NOTE;
789- return size;
790- }
791- break;
792- case NT_NETBSD_MARCH:
793- if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
794- (const char *)&nbuf[doff]) == -1)
795- return size;
796- break;
797- case NT_NETBSD_CMODEL:
798- if (file_printf(ms, ", compiler model: %.*s",
799- (int)descsz, (const char *)&nbuf[doff]) == -1)
800- return size;
801- break;
802- default:
803- if (file_printf(ms, ", note=%u", xnh_type) == -1)
804- return size;
805- break;
806- }
807- return size;
808- }
809-
810- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
811- if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
812- do_note_freebsd_version(ms, swap, &nbuf[doff]);
813- *flags |= FLAGS_DID_NOTE;
814- return size;
815+ return 1;
816 }
817+ return 1;
818 }
819+ return 0;
820+}
821
822- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
823- xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
824- if (file_printf(ms, ", for OpenBSD") == -1)
825- return size;
826- /* Content of note is always 0 */
827- *flags |= FLAGS_DID_NOTE;
828- return size;
829- }
830-
831- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
832- xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
833- uint32_t desc;
834- if (file_printf(ms, ", for DragonFly") == -1)
835- return size;
836- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
837- desc = elf_getu32(swap, desc);
838- if (file_printf(ms, " %d.%d.%d", desc / 100000,
839- desc / 10000 % 10, desc % 10000) == -1)
840- return size;
841- *flags |= FLAGS_DID_NOTE;
842- return size;
843- }
844-
845-core:
846+private int
847+do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
848+ int swap, uint32_t namesz, uint32_t descsz,
849+ size_t noff, size_t doff, int *flags, size_t size, int clazz)
850+{
851+#ifdef ELFCORE
852+ int os_style = -1;
853 /*
854 * Sigh. The 2.0.36 kernel in Debian 2.1, at
855 * least, doesn't correctly implement name
856@@ -697,20 +668,17 @@ core:
857 os_style = OS_STYLE_NETBSD;
858 }
859
860-#ifdef ELFCORE
861- if ((*flags & FLAGS_DID_CORE) != 0)
862- return size;
863-
864 if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
865 if (file_printf(ms, ", %s-style", os_style_names[os_style])
866 == -1)
867- return size;
868+ return 1;
869 *flags |= FLAGS_DID_CORE_STYLE;
870 }
871
872 switch (os_style) {
873 case OS_STYLE_NETBSD:
874- if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
875+ if (type == NT_NETBSD_CORE_PROCINFO) {
876+ char sbuf[512];
877 uint32_t signo;
878 /*
879 * Extract the program name. It is at
880@@ -719,7 +687,7 @@ core:
881 */
882 if (file_printf(ms, ", from '%.31s'",
883 &nbuf[doff + 0x7c]) == -1)
884- return size;
885+ return 1;
886
887 /*
888 * Extract the signal number. It is at
889@@ -736,8 +704,7 @@ core:
890 break;
891
892 default:
893- if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
894-/*###709 [cc] warning: declaration of 'i' shadows previous non-variable%%%*/
895+ if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
896 size_t i, j;
897 unsigned char c;
898 /*
899@@ -805,7 +772,7 @@ core:
900 * Try next offsets, in case this match is
901 * in the middle of a string.
902 */
903- for (k = i + 1 ; k < NOFFSETS ; k++) {
904+ for (k = i + 1 ; k < NOFFSETS; k++) {
905 size_t no;
906 int adjust = 1;
907 if (prpsoffsets(k) >= prpsoffsets(i))
908@@ -830,9 +797,9 @@ core:
909 cp--;
910 if (file_printf(ms, ", from '%.*s'",
911 (int)(cp - cname), cname) == -1)
912- return size;
913+ return 1;
914 *flags |= FLAGS_DID_CORE;
915- return size;
916+ return 1;
917
918 tryanother:
919 ;
920@@ -841,6 +808,129 @@ core:
921 break;
922 }
923 #endif
924+ return 0;
925+}
926+
927+private size_t
928+donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
929+ int clazz, int swap, size_t align, int *flags, uint16_t *notecount)
930+{
931+ Elf32_Nhdr nh32;
932+ Elf64_Nhdr nh64;
933+ size_t noff, doff;
934+ uint32_t namesz, descsz;
935+ unsigned char *nbuf = CAST(unsigned char *, vbuf);
936+
937+ if (*notecount == 0)
938+ return 0;
939+ --*notecount;
940+
941+ if (xnh_sizeof + offset > size) {
942+ /*
943+ * We're out of note headers.
944+ */
945+ return xnh_sizeof + offset;
946+ }
947+
948+ (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
949+ offset += xnh_sizeof;
950+
951+ namesz = xnh_namesz;
952+ descsz = xnh_descsz;
953+ if ((namesz == 0) && (descsz == 0)) {
954+ /*
955+ * We're out of note headers.
956+ */
957+ return (offset >= size) ? offset : size;
958+ }
959+
960+ if (namesz & 0x80000000) {
961+ (void)file_printf(ms, ", bad note name size 0x%lx",
962+ (unsigned long)namesz);
963+ return 0;
964+ }
965+
966+ if (descsz & 0x80000000) {
967+ (void)file_printf(ms, ", bad note description size 0x%lx",
968+ (unsigned long)descsz);
969+ return 0;
970+ }
971+
972+ noff = offset;
973+ doff = ELF_ALIGN(offset + namesz);
974+
975+ if (offset + namesz > size) {
976+ /*
977+ * We're past the end of the buffer.
978+ */
979+ return doff;
980+ }
981+
982+ offset = ELF_ALIGN(doff + descsz);
983+ if (doff + descsz > size) {
984+ /*
985+ * We're past the end of the buffer.
986+ */
987+ return (offset >= size) ? offset : size;
988+ }
989+
990+ if ((*flags & FLAGS_DID_OS_NOTE) == 0) {
991+ if (do_os_note(ms, nbuf, xnh_type, swap,
992+ namesz, descsz, noff, doff, flags))
993+ return size;
994+ }
995+
996+ if ((*flags & FLAGS_DID_BUILD_ID) == 0) {
997+ if (do_bid_note(ms, nbuf, xnh_type, swap,
998+ namesz, descsz, noff, doff, flags))
999+ return size;
1000+ }
1001+
1002+ if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
1003+ if (do_pax_note(ms, nbuf, xnh_type, swap,
1004+ namesz, descsz, noff, doff, flags))
1005+ return size;
1006+ }
1007+
1008+ if ((*flags & FLAGS_DID_CORE) == 0) {
1009+ if (do_core_note(ms, nbuf, xnh_type, swap,
1010+ namesz, descsz, noff, doff, flags, size, clazz))
1011+ return size;
1012+ }
1013+
1014+ if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
1015+ if (descsz > 100)
1016+ descsz = 100;
1017+ switch (xnh_type) {
1018+ case NT_NETBSD_VERSION:
1019+ return size;
1020+ case NT_NETBSD_MARCH:
1021+ if (*flags & FLAGS_DID_NETBSD_MARCH)
1022+ return size;
1023+ *flags |= FLAGS_DID_NETBSD_MARCH;
1024+ if (file_printf(ms, ", compiled for: %.*s",
1025+ (int)descsz, (const char *)&nbuf[doff]) == -1)
1026+ return size;
1027+ break;
1028+ case NT_NETBSD_CMODEL:
1029+ if (*flags & FLAGS_DID_NETBSD_CMODEL)
1030+ return size;
1031+ *flags |= FLAGS_DID_NETBSD_CMODEL;
1032+ if (file_printf(ms, ", compiler model: %.*s",
1033+ (int)descsz, (const char *)&nbuf[doff]) == -1)
1034+ return size;
1035+ break;
1036+ default:
1037+ if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
1038+ return size;
1039+ *flags |= FLAGS_DID_NETBSD_UNKNOWN;
1040+ if (file_printf(ms, ", note=%u", xnh_type) == -1)
1041+ return size;
1042+ break;
1043+ }
1044+ return size;
1045+ }
1046+
1047 return offset;
1048 }
1049
1050@@ -896,16 +986,19 @@ static const cap_desc_t cap_desc_386[] =
1051
1052 private int
1053 doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
1054- size_t size, off_t fsize, int *flags, int mach, int strtab)
1055+ size_t size, off_t fsize, int mach, int strtab, int *flags,
1056+ uint16_t *notecount)
1057 {
1058 Elf32_Shdr sh32;
1059 Elf64_Shdr sh64;
1060 int stripped = 1;
1061+ size_t nbadcap = 0;
1062 void *nbuf;
1063 off_t noff, coff, name_off;
1064 uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
1065 uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
1066 char name[50];
1067+ ssize_t namesize;
1068
1069 if (size != xsh_sizeof) {
1070 if (file_printf(ms, ", corrupted section header size") == -1)
1071@@ -914,7 +1007,7 @@ doshn(struct magic_set *ms, int clazz, i
1072 }
1073
1074 /* Read offset of name section to be able to read section names later */
1075- if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
1076+ if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) < (ssize_t)xsh_sizeof) {
1077 file_badread(ms);
1078 return -1;
1079 }
1080@@ -922,15 +1015,15 @@ doshn(struct magic_set *ms, int clazz, i
1081
1082 for ( ; num; num--) {
1083 /* Read the name of this section. */
1084- if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
1085+ if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) {
1086 file_badread(ms);
1087 return -1;
1088 }
1089- name[sizeof(name) - 1] = '\0';
1090+ name[namesize] = '\0';
1091 if (strcmp(name, ".debug_info") == 0)
1092 stripped = 0;
1093
1094- if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
1095+ if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) {
1096 file_badread(ms);
1097 return -1;
1098 }
1099@@ -945,7 +1038,7 @@ doshn(struct magic_set *ms, int clazz, i
1100 stripped = 0;
1101 break;
1102 default:
1103- if (xsh_offset > fsize) {
1104+ if (fsize != SIZE_UNKNOWN && xsh_offset > fsize) {
1105 /* Perhaps warn here */
1106 continue;
1107 }
1108@@ -960,7 +1053,7 @@ doshn(struct magic_set *ms, int clazz, i
1109 " for note");
1110 return -1;
1111 }
1112- if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
1113+ if (pread(fd, nbuf, xsh_size, xsh_offset) < (ssize_t)xsh_size) {
1114 file_badread(ms);
1115 free(nbuf);
1116 return -1;
1117@@ -971,7 +1064,7 @@ doshn(struct magic_set *ms, int clazz, i
1118 if (noff >= (off_t)xsh_size)
1119 break;
1120 noff = donote(ms, nbuf, (size_t)noff,
1121- xsh_size, clazz, swap, 4, flags);
1122+ xsh_size, clazz, swap, 4, flags, notecount);
1123 if (noff == 0)
1124 break;
1125 }
1126@@ -989,6 +1082,8 @@ doshn(struct magic_set *ms, int clazz, i
1127 goto skip;
1128 }
1129
1130+ if (nbadcap > 5)
1131+ break;
1132 if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
1133 file_badseek(ms);
1134 return -1;
1135@@ -1024,6 +1119,8 @@ doshn(struct magic_set *ms, int clazz, i
1136 (unsigned long long)xcap_tag,
1137 (unsigned long long)xcap_val) == -1)
1138 return -1;
1139+ if (nbadcap++ > 2)
1140+ coff = xsh_size;
1141 break;
1142 }
1143 }
1144@@ -1104,7 +1201,8 @@ doshn(struct magic_set *ms, int clazz, i
1145 */
1146 private int
1147 dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
1148- int num, size_t size, off_t fsize, int *flags, int sh_num)
1149+ int num, size_t size, off_t fsize, int sh_num, int *flags,
1150+ uint16_t *notecount)
1151 {
1152 Elf32_Phdr ph32;
1153 Elf64_Phdr ph64;
1154@@ -1121,7 +1219,7 @@ dophn_exec(struct magic_set *ms, int cla
1155 }
1156
1157 for ( ; num; num--) {
1158- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
1159+ if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
1160 file_badread(ms);
1161 return -1;
1162 }
1163@@ -1137,7 +1235,7 @@ dophn_exec(struct magic_set *ms, int cla
1164 shared_libraries = " (uses shared libs)";
1165 break;
1166 default:
1167- if (xph_offset > fsize) {
1168+ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
1169 /* Maybe warn here? */
1170 continue;
1171 }
1172@@ -1173,7 +1271,7 @@ dophn_exec(struct magic_set *ms, int cla
1173 break;
1174 offset = donote(ms, nbuf, offset,
1175 (size_t)bufsize, clazz, swap, align,
1176- flags);
1177+ flags, notecount);
1178 if (offset == 0)
1179 break;
1180 }
1181@@ -1204,7 +1302,7 @@ file_tryelf(struct magic_set *ms, int fd
1182 int flags = 0;
1183 Elf32_Ehdr elf32hdr;
1184 Elf64_Ehdr elf64hdr;
1185- uint16_t type;
1186+ uint16_t type, phnum, shnum, notecount;
1187
1188 if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
1189 return 0;
1190@@ -1230,7 +1328,10 @@ file_tryelf(struct magic_set *ms, int fd
1191 file_badread(ms);
1192 return -1;
1193 }
1194- fsize = st.st_size;
1195+ if (S_ISREG(st.st_mode))
1196+ fsize = st.st_size;
1197+ else
1198+ fsize = SIZE_UNKNOWN;
1199
1200 clazz = buf[EI_CLASS];
1201
1202Index: file-5.16/src/softmagic.c
1203===================================================================
1204--- file-5.16.orig/src/softmagic.c
1205+++ file-5.16/src/softmagic.c
1206@@ -43,11 +43,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.1
1207
1208
1209 private int match(struct magic_set *, struct magic *, uint32_t,
1210- const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
1211- int *);
1212+ const unsigned char *, size_t, size_t, int, int, int, uint16_t,
1213+ uint16_t *, int *, int *, int *);
1214 private int mget(struct magic_set *, const unsigned char *,
1215- struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *,
1216- int *, int *);
1217+ struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t,
1218+ uint16_t *, int *, int *, int *);
1219 private int magiccheck(struct magic_set *, struct magic *);
1220 private int32_t mprint(struct magic_set *, struct magic *);
1221 private int32_t moffset(struct magic_set *, struct magic *);
1222@@ -69,14 +69,20 @@ private void cvt_64(union VALUETYPE *, c
1223 /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
1224 protected int
1225 file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
1226- int mode, int text)
1227+ uint16_t indir_level, uint16_t *name_count, int mode, int text)
1228 {
1229 struct mlist *ml;
1230 int rv, printed_something = 0, need_separator = 0;
1231+ uint16_t nc;
1232+
1233+ if (name_count == NULL) {
1234+ nc = 0;
1235+ name_count = &nc;
1236+ }
1237 for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
1238 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
1239- text, 0, 0, &printed_something, &need_separator,
1240- NULL)) != 0)
1241+ text, 0, indir_level, name_count,
1242+ &printed_something, &need_separator, NULL)) != 0)
1243 return rv;
1244
1245 return 0;
1246@@ -112,8 +118,8 @@ file_softmagic(struct magic_set *ms, con
1247 private int
1248 match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
1249 const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
1250- int flip, int recursion_level, int *printed_something, int *need_separator,
1251- int *returnval)
1252+ int flip, uint16_t indir_level, uint16_t *name_count,
1253+ int *printed_something, int *need_separator, int *returnval)
1254 {
1255 uint32_t magindex = 0;
1256 unsigned int cont_level = 0;
1257@@ -150,8 +156,8 @@ match(struct magic_set *ms, struct magic
1258
1259 /* if main entry matches, print it... */
1260 switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
1261- flip, recursion_level + 1, printed_something,
1262- need_separator, returnval)) {
1263+ flip, indir_level, name_count,
1264+ printed_something, need_separator, returnval)) {
1265 case -1:
1266 return -1;
1267 case 0:
1268@@ -237,8 +243,8 @@ match(struct magic_set *ms, struct magic
1269 }
1270 #endif
1271 switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
1272- text, flip, recursion_level + 1, printed_something,
1273- need_separator, returnval)) {
1274+ text, flip, indir_level, name_count,
1275+ printed_something, need_separator, returnval)) {
1276 case -1:
1277 return -1;
1278 case 0:
1279@@ -1120,8 +1126,8 @@ mcopy(struct magic_set *ms, union VALUET
1280 private int
1281 mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
1282 size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
1283- int flip, int recursion_level, int *printed_something,
1284- int *need_separator, int *returnval)
1285+ int flip, uint16_t indir_level, uint16_t *name_count,
1286+ int *printed_something, int *need_separator, int *returnval)
1287 {
1288 uint32_t soffset, offset = ms->offset;
1289 uint32_t count = m->str_range;
1290@@ -1130,8 +1136,15 @@ mget(struct magic_set *ms, const unsigne
1291 union VALUETYPE *p = &ms->ms_value;
1292 struct mlist ml;
1293
1294- if (recursion_level >= 20) {
1295- file_error(ms, 0, "recursion nesting exceeded");
1296+ if (indir_level >= ms->indir_max) {
1297+ file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
1298+ indir_level);
1299+ return -1;
1300+ }
1301+
1302+ if (*name_count >= ms->name_max) {
1303+ file_error(ms, 0, "name use count (%hu) exceeded",
1304+ *name_count);
1305 return -1;
1306 }
1307
1308@@ -1141,8 +1154,9 @@ mget(struct magic_set *ms, const unsigne
1309
1310 if ((ms->flags & MAGIC_DEBUG) != 0) {
1311 fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
1312- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
1313- nbytes, count);
1314+ "nbytes=%zu, il=%hu, nc=%hu)\n",
1315+ m->type, m->flag, offset, o, nbytes,
1316+ indir_level, *name_count);
1317 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
1318 #ifndef COMPILE_ONLY
1319 file_mdump(m);
1320@@ -1711,7 +1725,7 @@ mget(struct magic_set *ms, const unsigne
1321 ms->o.buf = NULL;
1322 ms->offset = 0;
1323 rv = file_softmagic(ms, s + offset, nbytes - offset,
1324- BINTEST, text);
1325+ indir_level + 1, name_count, BINTEST, text);
1326 if ((ms->flags & MAGIC_DEBUG) != 0)
1327 fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
1328 rbuf = ms->o.buf;
1329@@ -1730,22 +1744,22 @@ mget(struct magic_set *ms, const unsigne
1330 case FILE_USE:
1331 if (nbytes < offset)
1332 return 0;
1333- sbuf = m->value.s;
1334- if (*sbuf == '^') {
1335- sbuf++;
1336+ rbuf = m->value.s;
1337+ if (*rbuf == '^') {
1338+ rbuf++;
1339 flip = !flip;
1340 }
1341- if (file_magicfind(ms, sbuf, &ml) == -1) {
1342- file_error(ms, 0, "cannot find entry `%s'", sbuf);
1343+ if (file_magicfind(ms, rbuf, &ml) == -1) {
1344+ file_error(ms, 0, "cannot find entry `%s'", rbuf);
1345 return -1;
1346 }
1347-
1348+ (*name_count)++;
1349 oneed_separator = *need_separator;
1350 if (m->flag & NOSPACE)
1351 *need_separator = 0;
1352 rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
1353- mode, text, flip, recursion_level, printed_something,
1354- need_separator, returnval);
1355+ mode, text, flip, indir_level, name_count,
1356+ printed_something, need_separator, returnval);
1357 if (rv != 1)
1358 *need_separator = oneed_separator;
1359 return rv;
diff --git a/meta/recipes-devtools/file/file_5.16.bb b/meta/recipes-devtools/file/file_5.16.bb
index a15d952e3d..f231a55059 100644
--- a/meta/recipes-devtools/file/file_5.16.bb
+++ b/meta/recipes-devtools/file/file_5.16.bb
@@ -12,6 +12,7 @@ DEPENDS = "zlib file-native"
12DEPENDS_class-native = "zlib-native" 12DEPENDS_class-native = "zlib-native"
13 13
14SRC_URI = "ftp://ftp.astron.com/pub/file/file-${PV}.tar.gz \ 14SRC_URI = "ftp://ftp.astron.com/pub/file/file-${PV}.tar.gz \
15 file://file-CVE-2014-9620-and-CVE-2014-9621.patch \
15 file://dump \ 16 file://dump \
16 file://filesystems" 17 file://filesystems"
17 18