diff options
author | Chong Lu <Chong.Lu@windriver.com> | 2015-01-22 17:28:34 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-02-06 14:56:07 +0000 |
commit | 46e8377c42030eb04972940cd022a8d214d477c7 (patch) | |
tree | 4bf54419eb27d1e8eb1c715ed1f55ab3d2d4b2b2 | |
parent | 148b7d20d40588e3dd34fddaec850b7238c580ce (diff) | |
download | poky-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>
-rw-r--r-- | meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch | 1359 | ||||
-rw-r--r-- | meta/recipes-devtools/file/file_5.16.bb | 1 |
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 @@ | |||
1 | file: CVE-2014-9620 and CVE-2014-9621 | ||
2 | |||
3 | The patch comes from: | ||
4 | https://github.com/file/file/commit/6ce24f35cd4a43c4bdd249e8e0c4952c1f8eac67 | ||
5 | https://github.com/file/file/commit/0056ec32255de1de973574b0300161a1568767d6 | ||
6 | https://github.com/file/file/commit/09e41625c999a2e5b51e1092f0ef2432a99b5c33 | ||
7 | https://github.com/file/file/commit/af444af0738468393f40f9d2261b1ea10fc4b2ba | ||
8 | https://github.com/file/file/commit/68bd8433c7e11a8dbe100deefdfac69138ee7cd9 | ||
9 | https://github.com/file/file/commit/dddd3cdb95210a765dd90f7d722cb8b5534daee7 | ||
10 | https://github.com/file/file/commit/445c8fb0ebff85195be94cd9f7e1df89cade5c7f | ||
11 | https://github.com/file/file/commit/ce90e05774dd77d86cfc8dfa6da57b32816841c4 | ||
12 | https://github.com/file/file/commit/65437cee25199dbd385fb35901bc0011e164276c | ||
13 | |||
14 | Upstream-Status: Backport | ||
15 | |||
16 | Signed-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 | |||
32 | Index: 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); | ||
48 | Index: 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 | |||
62 | Index: 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, ¬ecount) == -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, ¬ecount) == -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, ¬ecount) == -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; | ||
129 | Index: 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*/ | ||
240 | Index: 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; | ||
285 | Index: 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") | ||
302 | Index: 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 | +} | ||
359 | Index: 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 | +} | ||
417 | Index: 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 | ||
437 | Index: 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 | ||
457 | Index: 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 | |||
1202 | Index: 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" | |||
12 | DEPENDS_class-native = "zlib-native" | 12 | DEPENDS_class-native = "zlib-native" |
13 | 13 | ||
14 | SRC_URI = "ftp://ftp.astron.com/pub/file/file-${PV}.tar.gz \ | 14 | SRC_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 | ||