[OE-core] [daisy][PATCH] file: CVE-2014-9620 and CVE-2014-9621
Chong Lu
Chong.Lu at windriver.com
Tue Feb 3 01:23:30 UTC 2015
On 02/02/2015 09:55 PM, Saul Wold wrote:
>
> I had some issues with this patch on the Autobuilder, it failed in
> some cases for nativesdk-file on some, but not all machines of the
> autobuilder.
>
> See:
> https://autobuilder.yoctoproject.org/main/builders/nightly-arm/builds/178/steps/Building%20Toolchain%20Images/logs/stdio
>
> That's one example of the failure.
OK. I will fix and resend one.
Best Regards
Chong
>
> Sau!
>
>
>
> On 01/22/2015 01:28 AM, Chong Lu wrote:
>> 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]
>>
>> Signed-off-by: Chong Lu <Chong.Lu at windriver.com>
>> ---
>> .../file-CVE-2014-9620-and-CVE-2014-9621.patch | 1357
>> ++++++++++++++++++++
>> meta/recipes-devtools/file/file_5.16.bb | 1 +
>> 2 files changed, 1358 insertions(+)
>> create mode 100644
>> meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch
>>
>> 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 0000000..bd5944e
>> --- /dev/null
>> +++
>> b/meta/recipes-devtools/file/file/file-CVE-2014-9620-and-CVE-2014-9621.patch
>> @@ -0,0 +1,1357 @@
>> +file: CVE-2014-9620 and CVE-2014-9621
>> +
>> +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
>>
>> +
>> +Upstream-Status: Backport
>> +
>> +Signed-off-by: Chong Lu <Chong.Lu at windriver.com>
>> +---
>> + src/apprentice.c | 5 +
>> + src/ascmagic.c | 3 +-
>> + src/elfclass.h | 34 ++--
>> + src/file.c | 58 ++++++-
>> + src/file.h | 20 ++-
>> + src/file_opts.h | 6 +
>> + src/funcs.c | 42 ++++-
>> + src/magic.c | 50 ++++++
>> + src/magic.h | 9 ++
>> + src/magic.h.in | 4 +
>> + src/readelf.c | 467
>> +++++++++++++++++++++++++++++++++---------------------
>> + src/softmagic.c | 70 ++++----
>> + 12 files changed, 541 insertions(+), 227 deletions(-)
>> +
>> +diff --git a/src/apprentice.c b/src/apprentice.c
>> +index 2df60d9..d906f7b 100644
>> +--- a/src/apprentice.c
>> ++++ b/src/apprentice.c
>> +@@ -494,6 +494,11 @@ file_ms_alloc(int flags)
>> + ms->mlist[i] = NULL;
>> + ms->file = "unknown";
>> + ms->line = 0;
>> ++ ms->indir_max = FILE_INDIR_MAX;
>> ++ ms->name_max = FILE_NAME_MAX;
>> ++ ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
>> ++ ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
>> ++ ms->elf_notes_max = FILE_ELF_NOTES_MAX;
>> + return ms;
>> + free:
>> + free(ms);
>> +diff --git a/src/ascmagic.c b/src/ascmagic.c
>> +index 28ebadc..7a22328 100644
>> +--- a/src/ascmagic.c
>> ++++ b/src/ascmagic.c
>> +@@ -147,7 +147,8 @@ file_ascmagic_with_encoding(struct magic_set
>> *ms, const unsigned char *buf,
>> + == NULL)
>> + goto done;
>> + if ((rv = file_softmagic(ms, utf8_buf,
>> +- (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0)
>> ++ (size_t)(utf8_end - utf8_buf), 0, NULL,
>> ++ TEXTTEST, text)) == 0)
>> + rv = -1;
>> + }
>> +
>> +diff --git a/src/elfclass.h b/src/elfclass.h
>> +index 010958a..5360b0b 100644
>> +--- a/src/elfclass.h
>> ++++ b/src/elfclass.h
>> +@@ -32,39 +32,51 @@
>> + swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
>> +
>> + type = elf_getu16(swap, elfhdr.e_type);
>> ++ notecount = ms->elf_notes_max;
>> + switch (type) {
>> + #ifdef ELFCORE
>> + case ET_CORE:
>> ++ phnum = elf_getu16(swap, elfhdr.e_phnum);
>> ++ if (phnum > ms->elf_phnum_max)
>> ++ return toomany(ms, "program headers", phnum);
>> + flags |= FLAGS_IS_CORE;
>> + if (dophn_core(ms, clazz, swap, fd,
>> +- (off_t)elf_getu(swap, elfhdr.e_phoff),
>> +- elf_getu16(swap, elfhdr.e_phnum),
>> ++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
>> + (size_t)elf_getu16(swap, elfhdr.e_phentsize),
>> +- fsize, &flags) == -1)
>> ++ fsize, &flags, ¬ecount) == -1)
>> + return -1;
>> + break;
>> + #endif
>> + case ET_EXEC:
>> + case ET_DYN:
>> ++ phnum = elf_getu16(swap, elfhdr.e_phnum);
>> ++ if (phnum > ms->elf_phnum_max)
>> ++ return toomany(ms, "program", phnum);
>> ++ shnum = elf_getu16(swap, elfhdr.e_shnum);
>> ++ if (shnum > ms->elf_shnum_max)
>> ++ return toomany(ms, "section", shnum);
>> + if (dophn_exec(ms, clazz, swap, fd,
>> +- (off_t)elf_getu(swap, elfhdr.e_phoff),
>> +- elf_getu16(swap, elfhdr.e_phnum),
>> ++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
>> + (size_t)elf_getu16(swap, elfhdr.e_phentsize),
>> +- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
>> +- == -1)
>> ++ fsize, shnum, &flags, ¬ecount) == -1)
>> + return -1;
>> + /*FALLTHROUGH*/
>> + case ET_REL:
>> ++ shnum = elf_getu16(swap, elfhdr.e_shnum);
>> ++ if (shnum > ms->elf_shnum_max)
>> ++ return toomany(ms, "section headers", shnum);
>> + if (doshn(ms, clazz, swap, fd,
>> +- (off_t)elf_getu(swap, elfhdr.e_shoff),
>> +- elf_getu16(swap, elfhdr.e_shnum),
>> ++ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
>> + (size_t)elf_getu16(swap, elfhdr.e_shentsize),
>> +- fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
>> +- (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
>> ++ fsize, elf_getu16(swap, elfhdr.e_machine),
>> ++ (int)elf_getu16(swap, elfhdr.e_shstrndx),
>> ++ &flags, ¬ecount) == -1)
>> + return -1;
>> + break;
>> +
>> + default:
>> + break;
>> + }
>> ++ if (notecount == 0)
>> ++ return toomany(ms, "notes", ms->elf_notes_max);
>> + return 1;
>> +diff --git a/src/file.c b/src/file.c
>> +index ac773ea..ee1edcd 100644
>> +--- a/src/file.c
>> ++++ b/src/file.c
>> +@@ -101,7 +101,7 @@ private const struct option long_options[] = {
>> + #undef OPT_LONGONLY
>> + {0, 0, NULL, 0}
>> + };
>> +-#define OPTSTRING "bcCde:f:F:hiklLm:nNprsvz0"
>> ++#define OPTSTRING "bcCde:f:F:hiklLm:nNpP:rsvz0"
>> +
>> + private const struct {
>> + const char *name;
>> +@@ -119,6 +119,18 @@ private const struct {
>> + { "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored
>> for backwards compatibility */
>> + };
>> +
>> ++private struct {
>> ++ const char *name;
>> ++ int tag;
>> ++ size_t value;
>> ++} pm[] = {
>> ++ { "indir", MAGIC_PARAM_INDIR_MAX, 0 },
>> ++ { "name", MAGIC_PARAM_NAME_MAX, 0 },
>> ++ { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
>> ++ { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
>> ++ { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
>> ++};
>> ++
>> + private char *progname; /* used throughout */
>> +
>> + private void usage(void);
>> +@@ -128,6 +140,8 @@ private void help(void);
>> + private int unwrap(struct magic_set *, const char *);
>> + private int process(struct magic_set *ms, const char *, int);
>> + private struct magic_set *load(const char *, int);
>> ++private void setparam(const char *);
>> ++private void applyparam(magic_t);
>> +
>> +
>> + /*
>> +@@ -240,6 +254,9 @@ main(int argc, char *argv[])
>> + flags |= MAGIC_PRESERVE_ATIME;
>> + break;
>> + #endif
>> ++ case 'P':
>> ++ setparam(optarg);
>> ++ break;
>> + case 'r':
>> + flags |= MAGIC_RAW;
>> + break;
>> +@@ -295,6 +312,8 @@ main(int argc, char *argv[])
>> + strerror(errno));
>> + return 1;
>> + }
>> ++
>> ++
>> + switch(action) {
>> + case FILE_CHECK:
>> + c = magic_check(magic, magicfile);
>> +@@ -318,7 +337,7 @@ main(int argc, char *argv[])
>> + if (magic == NULL)
>> + if ((magic = load(magicfile, flags)) == NULL)
>> + return 1;
>> +- break;
>> ++ applyparam(magic);
>> + }
>> +
>> + if (optind == argc) {
>> +@@ -348,6 +367,41 @@ main(int argc, char *argv[])
>> + return e;
>> + }
>> +
>> ++private void
>> ++applyparam(magic_t magic)
>> ++{
>> ++ size_t i;
>> ++
>> ++ for (i = 0; i < __arraycount(pm); i++) {
>> ++ if (pm[i].value == 0)
>> ++ continue;
>> ++ if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) {
>> ++ (void)fprintf(stderr, "%s: Can't set %s %s\n", progname,
>> ++ pm[i].name, strerror(errno));
>> ++ exit(1);
>> ++ }
>> ++ }
>> ++}
>> ++
>> ++private void
>> ++setparam(const char *p)
>> ++{
>> ++ size_t i;
>> ++ char *s;
>> ++
>> ++ if ((s = strchr(p, '=')) == NULL)
>> ++ goto badparm;
>> ++
>> ++ for (i = 0; i < __arraycount(pm); i++) {
>> ++ if (strncmp(p, pm[i].name, s - p) != 0)
>> ++ continue;
>> ++ pm[i].value = atoi(s + 1);
>> ++ return;
>> ++ }
>> ++badparm:
>> ++ (void)fprintf(stderr, "%s: Unknown param %s\n", progname, p);
>> ++ exit(1);
>> ++}
>> +
>> + private struct magic_set *
>> + /*ARGSUSED*/
>> +diff --git a/src/file.h b/src/file.h
>> +index e910a2b..57e7307 100644
>> +--- a/src/file.h
>> ++++ b/src/file.h
>> +@@ -400,6 +400,16 @@ struct magic_set {
>> + /* FIXME: Make the string dynamically allocated so that e.g.
>> + strings matched in files can be longer than MAXstring */
>> + union VALUETYPE ms_value; /* either number or string */
>> ++ uint16_t indir_max;
>> ++ uint16_t name_max;
>> ++ uint16_t elf_shnum_max;
>> ++ uint16_t elf_phnum_max;
>> ++ uint16_t elf_notes_max;
>> ++#define FILE_INDIR_MAX 15
>> ++#define FILE_NAME_MAX 30
>> ++#define FILE_ELF_SHNUM_MAX 32768
>> ++#define FILE_ELF_PHNUM_MAX 128
>> ++#define FILE_ELF_NOTES_MAX 256
>> + };
>> +
>> + /* Type for Unicode characters */
>> +@@ -438,7 +448,7 @@ protected int file_encoding(struct magic_set *,
>> const unsigned char *, size_t,
>> + unichar **, size_t *, const char **, const char **, const char
>> **);
>> + protected int file_is_tar(struct magic_set *, const unsigned char
>> *, size_t);
>> + protected int file_softmagic(struct magic_set *, const unsigned
>> char *, size_t,
>> +- int, int);
>> ++ uint16_t, uint16_t *, int, int);
>> + protected int file_apprentice(struct magic_set *, const char *, int);
>> + protected int file_magicfind(struct magic_set *, const char *,
>> struct mlist *);
>> + protected uint64_t file_signextend(struct magic_set *, struct magic *,
>> +@@ -468,6 +478,14 @@ protected int file_os2_apptype(struct magic_set
>> *, const char *, const void *,
>> + #endif /* __EMX__ */
>> +
>> +
>> ++typedef struct {
>> ++ char *buf;
>> ++ uint32_t offset;
>> ++} file_pushbuf_t;
>> ++
>> ++protected file_pushbuf_t *file_push_buffer(struct magic_set *);
>> ++protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t
>> *);
>> ++
>> + #ifndef COMPILE_ONLY
>> + extern const char *file_names[];
>> + extern const size_t file_nnames;
>> +diff --git a/src/file_opts.h b/src/file_opts.h
>> +index db34eb7..3286ac6 100644
>> +--- a/src/file_opts.h
>> ++++ b/src/file_opts.h
>> +@@ -43,6 +43,12 @@ OPT('0', "print0", 0, " terminate filenames with
>> ASCII NUL\n")
>> + #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
>> + OPT('p', "preserve-date", 0, " preserve access times on
>> files\n")
>> + #endif
>> ++OPT('P', "parameter", 0, " set file engine parameter
>> limits\n"
>> ++ " indir 15 recursion limit
>> for indirection\n"
>> ++ " name 30 use limit for
>> name/use magic\n"
>> ++ " elf_notes 256 max ELF notes
>> processed\n"
>> ++ " elf_phnum 128 max ELF prog
>> sections processed\n"
>> ++ " elf_shnum 32768 max ELF
>> sections processed\n")
>> + OPT('r', "raw", 0, " don't translate unprintable
>> chars to \\ooo\n")
>> + OPT('s', "special-files", 0, " treat special (block/char
>> devices) files as\n"
>> + " ordinary ones\n")
>> +diff --git a/src/funcs.c b/src/funcs.c
>> +index b798e44..50c38e5 100644
>> +--- a/src/funcs.c
>> ++++ b/src/funcs.c
>> +@@ -226,7 +226,7 @@ file_buffer(struct magic_set *ms, int fd, const
>> char *inname __attribute__ ((unu
>> +
>> + /* try soft magic tests */
>> + if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
>> +- if ((m = file_softmagic(ms, ubuf, nb, BINTEST,
>> ++ if ((m = file_softmagic(ms, ubuf, nb, 0, NULL, BINTEST,
>> + looks_text)) != 0) {
>> + if ((ms->flags & MAGIC_DEBUG) != 0)
>> + (void)fprintf(stderr, "softmagic %d\n", m);
>> +@@ -459,3 +459,43 @@ file_replace(struct magic_set *ms, const char
>> *pat, const char *rep)
>> + return nm;
>> + }
>> + }
>> ++
>> ++protected file_pushbuf_t *
>> ++file_push_buffer(struct magic_set *ms)
>> ++{
>> ++ file_pushbuf_t *pb;
>> ++
>> ++ if (ms->event_flags & EVENT_HAD_ERR)
>> ++ return NULL;
>> ++
>> ++ if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
>> ++ return NULL;
>> ++
>> ++ pb->buf = ms->o.buf;
>> ++ pb->offset = ms->offset;
>> ++
>> ++ ms->o.buf = NULL;
>> ++ ms->offset = 0;
>> ++
>> ++ return pb;
>> ++}
>> ++
>> ++protected char *
>> ++file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
>> ++{
>> ++ char *rbuf;
>> ++
>> ++ if (ms->event_flags & EVENT_HAD_ERR) {
>> ++ free(pb->buf);
>> ++ free(pb);
>> ++ return NULL;
>> ++ }
>> ++
>> ++ rbuf = ms->o.buf;
>> ++
>> ++ ms->o.buf = pb->buf;
>> ++ ms->offset = pb->offset;
>> ++
>> ++ free(pb);
>> ++ return rbuf;
>> ++}
>> +diff --git a/src/magic.c b/src/magic.c
>> +index 22174b8..a89647c 100644
>> +--- a/src/magic.c
>> ++++ b/src/magic.c
>> +@@ -490,3 +490,53 @@ magic_version(void)
>> + {
>> + return MAGIC_VERSION;
>> + }
>> ++
>> ++public int
>> ++magic_setparam(struct magic_set *ms, int param, const void *val)
>> ++{
>> ++ switch (param) {
>> ++ case MAGIC_PARAM_INDIR_MAX:
>> ++ ms->indir_max = *(const size_t *)val;
>> ++ return 0;
>> ++ case MAGIC_PARAM_NAME_MAX:
>> ++ ms->name_max = *(const size_t *)val;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_PHNUM_MAX:
>> ++ ms->elf_phnum_max = *(const size_t *)val;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_SHNUM_MAX:
>> ++ ms->elf_shnum_max = *(const size_t *)val;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_NOTES_MAX:
>> ++ ms->elf_notes_max = *(const size_t *)val;
>> ++ return 0;
>> ++ default:
>> ++ errno = EINVAL;
>> ++ return -1;
>> ++ }
>> ++}
>> ++
>> ++public int
>> ++magic_getparam(struct magic_set *ms, int param, void *val)
>> ++{
>> ++ switch (param) {
>> ++ case MAGIC_PARAM_INDIR_MAX:
>> ++ *(size_t *)val = ms->indir_max;
>> ++ return 0;
>> ++ case MAGIC_PARAM_NAME_MAX:
>> ++ *(size_t *)val = ms->name_max;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_PHNUM_MAX:
>> ++ *(size_t *)val = ms->elf_phnum_max;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_SHNUM_MAX:
>> ++ *(size_t *)val = ms->elf_shnum_max;
>> ++ return 0;
>> ++ case MAGIC_PARAM_ELF_NOTES_MAX:
>> ++ *(size_t *)val = ms->elf_notes_max;
>> ++ return 0;
>> ++ default:
>> ++ errno = EINVAL;
>> ++ return -1;
>> ++ }
>> ++}
>> +diff --git a/src/magic.h b/src/magic.h
>> +index cc8ed68..2938a20 100644
>> +--- a/src/magic.h
>> ++++ b/src/magic.h
>> +@@ -101,6 +101,15 @@ int magic_check(magic_t, const char *);
>> + int magic_list(magic_t, const char *);
>> + int magic_errno(magic_t);
>> +
>> ++#define MAGIC_PARAM_INDIR_MAX 0
>> ++#define MAGIC_PARAM_NAME_MAX 1
>> ++#define MAGIC_PARAM_ELF_PHNUM_MAX 2
>> ++#define MAGIC_PARAM_ELF_SHNUM_MAX 3
>> ++#define MAGIC_PARAM_ELF_NOTES_MAX 4
>> ++
>> ++int magic_setparam(magic_t, int, const void *);
>> ++int magic_getparam(magic_t, int, void *);
>> ++
>> + #ifdef __cplusplus
>> + };
>> + #endif
>> +diff --git a/src/magic.h.in b/src/magic.h.in
>> +index 86fc41b..a256cf0 100644
>> +--- a/src/magic.h.in
>> ++++ b/src/magic.h.in
>> +@@ -101,6 +101,10 @@ int magic_check(magic_t, const char *);
>> + int magic_list(magic_t, const char *);
>> + int magic_errno(magic_t);
>> +
>> ++#define MAGIC_PARAM_MAX_RECURSION 0
>> ++int magic_setparam(magic_t, int, const void *);
>> ++int magic_getparam(magic_t, int, void *);
>> ++
>> + #ifdef __cplusplus
>> + };
>> + #endif
>> +diff --git a/src/readelf.c b/src/readelf.c
>> +index f8b8bbc..a7b2ba4 100644
>> +--- a/src/readelf.c
>> ++++ b/src/readelf.c
>> +@@ -43,14 +43,14 @@ FILE_RCSID("@(#)$File: readelf.c,v 1.99
>> 2013/11/05 15:44:01 christos Exp $")
>> +
>> + #ifdef ELFCORE
>> + private int dophn_core(struct magic_set *, int, int, int, off_t,
>> int, size_t,
>> +- off_t, int *);
>> ++ off_t, int *, uint16_t *);
>> + #endif
>> + private int dophn_exec(struct magic_set *, int, int, int, off_t,
>> int, size_t,
>> +- off_t, int *, int);
>> ++ off_t, int, int *, uint16_t *);
>> + private int doshn(struct magic_set *, int, int, int, off_t, int,
>> size_t,
>> +- off_t, int *, int, int);
>> ++ off_t, int, int, int *, uint16_t *);
>> + private size_t donote(struct magic_set *, void *, size_t, size_t, int,
>> +- int, size_t, int *);
>> ++ int, size_t, int *, uint16_t *);
>> +
>> + #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
>> +
>> +@@ -60,6 +60,19 @@ private uint16_t getu16(int, uint16_t);
>> + private uint32_t getu32(int, uint32_t);
>> + private uint64_t getu64(int, uint64_t);
>> +
>> ++#define MAX_PHNUM 128
>> ++#define MAX_SHNUM 32768
>> ++#define SIZE_UNKNOWN ((off_t)-1)
>> ++
>> ++private int
>> ++toomany(struct magic_set *ms, const char *name, uint16_t num)
>> ++{
>> ++ if (file_printf(ms, ", too many %s (%u)", name, num
>> ++ ) == -1)
>> ++ return -1;
>> ++ return 0;
>> ++}
>> ++
>> + private uint16_t
>> + getu16(int swap, uint16_t value)
>> + {
>> +@@ -280,15 +293,19 @@ private const char os_style_names[][8] = {
>> + "NetBSD",
>> + };
>> +
>> +-#define FLAGS_DID_CORE 0x01
>> +-#define FLAGS_DID_NOTE 0x02
>> +-#define FLAGS_DID_BUILD_ID 0x04
>> +-#define FLAGS_DID_CORE_STYLE 0x08
>> +-#define FLAGS_IS_CORE 0x10
>> ++#define FLAGS_DID_CORE 0x001
>> ++#define FLAGS_DID_OS_NOTE 0x002
>> ++#define FLAGS_DID_BUILD_ID 0x004
>> ++#define FLAGS_DID_CORE_STYLE 0x008
>> ++#define FLAGS_DID_NETBSD_PAX 0x010
>> ++#define FLAGS_DID_NETBSD_MARCH 0x020
>> ++#define FLAGS_DID_NETBSD_CMODEL 0x040
>> ++#define FLAGS_DID_NETBSD_UNKNOWN 0x080
>> ++#define FLAGS_IS_CORE 0x100
>> +
>> + private int
>> + dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t
>> off,
>> +- int num, size_t size, off_t fsize, int *flags)
>> ++ int num, size_t size, off_t fsize, int *flags, uint16_t
>> *notecount)
>> + {
>> + Elf32_Phdr ph32;
>> + Elf64_Phdr ph64;
>> +@@ -306,13 +323,13 @@ dophn_core(struct magic_set *ms, int clazz,
>> int swap, int fd, off_t off,
>> + * Loop through all the program headers.
>> + */
>> + for ( ; num; num--) {
>> +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
>> ++ if (pread(fd, xph_addr, xph_sizeof, off) <
>> (ssize_t)xph_sizeof) {
>> + file_badread(ms);
>> + return -1;
>> + }
>> + off += size;
>> +
>> +- if (xph_offset > fsize) {
>> ++ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
>> + /* Perhaps warn here */
>> + continue;
>> + }
>> +@@ -334,7 +351,7 @@ dophn_core(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off,
>> + if (offset >= (size_t)bufsize)
>> + break;
>> + offset = donote(ms, nbuf, offset, (size_t)bufsize,
>> +- clazz, swap, 4, flags);
>> ++ clazz, swap, 4, flags, notecount);
>> + if (offset == 0)
>> + break;
>> +
>> +@@ -464,125 +481,127 @@ do_note_freebsd_version(struct magic_set
>> *ms, int swap, void *v)
>> + }
>> + }
>> +
>> +-private size_t
>> +-donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
>> +- int clazz, int swap, size_t align, int *flags)
>> ++private int
>> ++do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
>> ++ int swap __attribute__((__unused__)), uint32_t namesz, uint32_t
>> descsz,
>> ++ size_t noff, size_t doff, int *flags)
>> + {
>> +- Elf32_Nhdr nh32;
>> +- Elf64_Nhdr nh64;
>> +- size_t noff, doff;
>> +-#ifdef ELFCORE
>> +- int os_style = -1;
>> +-#endif
>> +- uint32_t namesz, descsz;
>> +- unsigned char *nbuf = CAST(unsigned char *, vbuf);
>> +-
>> +- (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
>> +- offset += xnh_sizeof;
>> +-
>> +- namesz = xnh_namesz;
>> +- descsz = xnh_descsz;
>> +- if ((namesz == 0) && (descsz == 0)) {
>> +- /*
>> +- * We're out of note headers.
>> +- */
>> +- return (offset >= size) ? offset : size;
>> +- }
>> +-
>> +- if (namesz & 0x80000000) {
>> +- (void)file_printf(ms, ", bad note name size 0x%lx",
>> +- (unsigned long)namesz);
>> +- return offset;
>> +- }
>> +-
>> +- if (descsz & 0x80000000) {
>> +- (void)file_printf(ms, ", bad note description size 0x%lx",
>> +- (unsigned long)descsz);
>> +- return offset;
>> +- }
>> +-
>> +-
>> +- noff = offset;
>> +- doff = ELF_ALIGN(offset + namesz);
>> +-
>> +- if (offset + namesz > size) {
>> +- /*
>> +- * We're past the end of the buffer.
>> +- */
>> +- return doff;
>> +- }
>> +-
>> +- offset = ELF_ALIGN(doff + descsz);
>> +- if (doff + descsz > size) {
>> +- /*
>> +- * We're past the end of the buffer.
>> +- */
>> +- return (offset >= size) ? offset : size;
>> ++ if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
>> ++ type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
>> ++ uint8_t desc[20];
>> ++ uint32_t i;
>> ++ *flags |= FLAGS_DID_BUILD_ID;
>> ++ if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ?
>> "md5/uuid" :
>> ++ "sha1") == -1)
>> ++ return 1;
>> ++ (void)memcpy(desc, &nbuf[doff], descsz);
>> ++ for (i = 0; i < descsz; i++)
>> ++ if (file_printf(ms, "%02x", desc[i]) == -1)
>> ++ return 1;
>> ++ return 1;
>> + }
>> +-
>> +- if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) ==
>> +- (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
>> +- goto core;
>> +-
>> ++ return 0;
>> ++}
>> ++
>> ++private int
>> ++do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
>> ++ int swap, uint32_t namesz, uint32_t descsz,
>> ++ size_t noff, size_t doff, int *flags)
>> ++{
>> + if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
>> +- xnh_type == NT_GNU_VERSION && descsz == 2) {
>> ++ type == NT_GNU_VERSION && descsz == 2) {
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> + file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff +
>> 1]);
>> ++ return 1;
>> + }
>> ++
>> + if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
>> +- xnh_type == NT_GNU_VERSION && descsz == 16) {
>> ++ type == NT_GNU_VERSION && descsz == 16) {
>> + uint32_t desc[4];
>> + (void)memcpy(desc, &nbuf[doff], sizeof(desc));
>> +
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> + if (file_printf(ms, ", for GNU/") == -1)
>> +- return size;
>> ++ return 1;
>> + switch (elf_getu32(swap, desc[0])) {
>> + case GNU_OS_LINUX:
>> + if (file_printf(ms, "Linux") == -1)
>> +- return size;
>> ++ return 1;
>> + break;
>> + case GNU_OS_HURD:
>> + if (file_printf(ms, "Hurd") == -1)
>> +- return size;
>> ++ return 1;
>> + break;
>> + case GNU_OS_SOLARIS:
>> + if (file_printf(ms, "Solaris") == -1)
>> +- return size;
>> ++ return 1;
>> + break;
>> + case GNU_OS_KFREEBSD:
>> + if (file_printf(ms, "kFreeBSD") == -1)
>> +- return size;
>> ++ return 1;
>> + break;
>> + case GNU_OS_KNETBSD:
>> + if (file_printf(ms, "kNetBSD") == -1)
>> +- return size;
>> ++ return 1;
>> + break;
>> + default:
>> + if (file_printf(ms, "<unknown>") == -1)
>> +- return size;
>> ++ return 1;
>> + }
>> + if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
>> + elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3]))
>> == -1)
>> +- return size;
>> +- *flags |= FLAGS_DID_NOTE;
>> +- return size;
>> ++ return 1;
>> ++ return 1;
>> + }
>> +
>> +- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
>> +- xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz ==
>> 20)) {
>> +- uint8_t desc[20];
>> +- uint32_t i;
>> +- if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ?
>> "md5/uuid" :
>> +- "sha1") == -1)
>> +- return size;
>> +- (void)memcpy(desc, &nbuf[doff], descsz);
>> +- for (i = 0; i < descsz; i++)
>> +- if (file_printf(ms, "%02x", desc[i]) == -1)
>> +- return size;
>> +- *flags |= FLAGS_DID_BUILD_ID;
>> ++ if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
>> ++ if (type == NT_NETBSD_VERSION && descsz == 4) {
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> ++ do_note_netbsd_version(ms, swap, &nbuf[doff]);
>> ++ return 1;
>> ++ }
>> ++ }
>> ++
>> ++ if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
>> ++ if (type == NT_FREEBSD_VERSION && descsz == 4) {
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> ++ do_note_freebsd_version(ms, swap, &nbuf[doff]);
>> ++ return 1;
>> ++ }
>> ++ }
>> ++
>> ++ if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
>> ++ type == NT_OPENBSD_VERSION && descsz == 4) {
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> ++ if (file_printf(ms, ", for OpenBSD") == -1)
>> ++ return 1;
>> ++ /* Content of note is always 0 */
>> ++ return 1;
>> ++ }
>> ++
>> ++ if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") ==
>> 0 &&
>> ++ type == NT_DRAGONFLY_VERSION && descsz == 4) {
>> ++ uint32_t desc;
>> ++ *flags |= FLAGS_DID_OS_NOTE;
>> ++ if (file_printf(ms, ", for DragonFly") == -1)
>> ++ return 1;
>> ++ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
>> ++ desc = elf_getu32(swap, desc);
>> ++ if (file_printf(ms, " %d.%d.%d", desc / 100000,
>> ++ desc / 10000 % 10, desc % 10000) == -1)
>> ++ return 1;
>> ++ return 1;
>> + }
>> ++ return 0;
>> ++}
>> +
>> ++private int
>> ++do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
>> ++ int swap, uint32_t namesz, uint32_t descsz,
>> ++ size_t noff, size_t doff, int *flags)
>> ++{
>> + if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
>> +- xnh_type == NT_NETBSD_PAX && descsz == 4) {
>> ++ type == NT_NETBSD_PAX && descsz == 4) {
>> + static const char *pax[] = {
>> + "+mprotect",
>> + "-mprotect",
>> +@@ -595,80 +614,32 @@ donote(struct magic_set *ms, void *vbuf,
>> size_t offset, size_t size,
>> + size_t i;
>> + int did = 0;
>> +
>> ++ *flags |= FLAGS_DID_NETBSD_PAX;
>> + (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
>> + desc = elf_getu32(swap, desc);
>> +
>> + if (desc && file_printf(ms, ", PaX: ") == -1)
>> +- return size;
>> ++ return 1;
>> +
>> + for (i = 0; i < __arraycount(pax); i++) {
>> + if (((1 << i) & desc) == 0)
>> + continue;
>> + if (file_printf(ms, "%s%s", did++ ? "," : "",
>> + pax[i]) == -1)
>> +- return size;
>> +- }
>> +- }
>> +-
>> +- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
>> +- switch (xnh_type) {
>> +- case NT_NETBSD_VERSION:
>> +- if (descsz == 4) {
>> +- do_note_netbsd_version(ms, swap, &nbuf[doff]);
>> +- *flags |= FLAGS_DID_NOTE;
>> +- return size;
>> +- }
>> +- break;
>> +- case NT_NETBSD_MARCH:
>> +- if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
>> +- (const char *)&nbuf[doff]) == -1)
>> +- return size;
>> +- break;
>> +- case NT_NETBSD_CMODEL:
>> +- if (file_printf(ms, ", compiler model: %.*s",
>> +- (int)descsz, (const char *)&nbuf[doff]) == -1)
>> +- return size;
>> +- break;
>> +- default:
>> +- if (file_printf(ms, ", note=%u", xnh_type) == -1)
>> +- return size;
>> +- break;
>> +- }
>> +- return size;
>> +- }
>> +-
>> +- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
>> +- if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
>> +- do_note_freebsd_version(ms, swap, &nbuf[doff]);
>> +- *flags |= FLAGS_DID_NOTE;
>> +- return size;
>> ++ return 1;
>> + }
>> ++ return 1;
>> + }
>> ++ return 0;
>> ++}
>> +
>> +- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
>> +- xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
>> +- if (file_printf(ms, ", for OpenBSD") == -1)
>> +- return size;
>> +- /* Content of note is always 0 */
>> +- *flags |= FLAGS_DID_NOTE;
>> +- return size;
>> +- }
>> +-
>> +- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") ==
>> 0 &&
>> +- xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
>> +- uint32_t desc;
>> +- if (file_printf(ms, ", for DragonFly") == -1)
>> +- return size;
>> +- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
>> +- desc = elf_getu32(swap, desc);
>> +- if (file_printf(ms, " %d.%d.%d", desc / 100000,
>> +- desc / 10000 % 10, desc % 10000) == -1)
>> +- return size;
>> +- *flags |= FLAGS_DID_NOTE;
>> +- return size;
>> +- }
>> +-
>> +-core:
>> ++private int
>> ++do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
>> ++ int swap, uint32_t namesz, uint32_t descsz,
>> ++ size_t noff, size_t doff, int *flags, size_t size, int clazz)
>> ++{
>> ++#ifdef ELFCORE
>> ++ int os_style = -1;
>> + /*
>> + * Sigh. The 2.0.36 kernel in Debian 2.1, at
>> + * least, doesn't correctly implement name
>> +@@ -697,20 +668,17 @@ core:
>> + os_style = OS_STYLE_NETBSD;
>> + }
>> +
>> +-#ifdef ELFCORE
>> +- if ((*flags & FLAGS_DID_CORE) != 0)
>> +- return size;
>> +-
>> + if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
>> + if (file_printf(ms, ", %s-style", os_style_names[os_style])
>> + == -1)
>> +- return size;
>> ++ return 1;
>> + *flags |= FLAGS_DID_CORE_STYLE;
>> + }
>> +
>> + switch (os_style) {
>> + case OS_STYLE_NETBSD:
>> +- if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
>> ++ if (type == NT_NETBSD_CORE_PROCINFO) {
>> ++ char sbuf[512];
>> + uint32_t signo;
>> + /*
>> + * Extract the program name. It is at
>> +@@ -719,7 +687,7 @@ core:
>> + */
>> + if (file_printf(ms, ", from '%.31s'",
>> + &nbuf[doff + 0x7c]) == -1)
>> +- return size;
>> ++ return 1;
>> +
>> + /*
>> + * Extract the signal number. It is at
>> +@@ -736,8 +704,7 @@ core:
>> + break;
>> +
>> + default:
>> +- if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
>> +-/*###709 [cc] warning: declaration of 'i' shadows previous
>> non-variable%%%*/
>> ++ if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
>> + size_t i, j;
>> + unsigned char c;
>> + /*
>> +@@ -805,7 +772,7 @@ core:
>> + * Try next offsets, in case this match is
>> + * in the middle of a string.
>> + */
>> +- for (k = i + 1 ; k < NOFFSETS ; k++) {
>> ++ for (k = i + 1 ; k < NOFFSETS; k++) {
>> + size_t no;
>> + int adjust = 1;
>> + if (prpsoffsets(k) >= prpsoffsets(i))
>> +@@ -830,9 +797,9 @@ core:
>> + cp--;
>> + if (file_printf(ms, ", from '%.*s'",
>> + (int)(cp - cname), cname) == -1)
>> +- return size;
>> ++ return 1;
>> + *flags |= FLAGS_DID_CORE;
>> +- return size;
>> ++ return 1;
>> +
>> + tryanother:
>> + ;
>> +@@ -841,6 +808,129 @@ core:
>> + break;
>> + }
>> + #endif
>> ++ return 0;
>> ++}
>> ++
>> ++private size_t
>> ++donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
>> ++ int clazz, int swap, size_t align, int *flags, uint16_t
>> *notecount)
>> ++{
>> ++ Elf32_Nhdr nh32;
>> ++ Elf64_Nhdr nh64;
>> ++ size_t noff, doff;
>> ++ uint32_t namesz, descsz;
>> ++ unsigned char *nbuf = CAST(unsigned char *, vbuf);
>> ++
>> ++ if (*notecount == 0)
>> ++ return 0;
>> ++ --*notecount;
>> ++
>> ++ if (xnh_sizeof + offset > size) {
>> ++ /*
>> ++ * We're out of note headers.
>> ++ */
>> ++ return xnh_sizeof + offset;
>> ++ }
>> ++
>> ++ (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
>> ++ offset += xnh_sizeof;
>> ++
>> ++ namesz = xnh_namesz;
>> ++ descsz = xnh_descsz;
>> ++ if ((namesz == 0) && (descsz == 0)) {
>> ++ /*
>> ++ * We're out of note headers.
>> ++ */
>> ++ return (offset >= size) ? offset : size;
>> ++ }
>> ++
>> ++ if (namesz & 0x80000000) {
>> ++ (void)file_printf(ms, ", bad note name size 0x%lx",
>> ++ (unsigned long)namesz);
>> ++ return 0;
>> ++ }
>> ++
>> ++ if (descsz & 0x80000000) {
>> ++ (void)file_printf(ms, ", bad note description size 0x%lx",
>> ++ (unsigned long)descsz);
>> ++ return 0;
>> ++ }
>> ++
>> ++ noff = offset;
>> ++ doff = ELF_ALIGN(offset + namesz);
>> ++
>> ++ if (offset + namesz > size) {
>> ++ /*
>> ++ * We're past the end of the buffer.
>> ++ */
>> ++ return doff;
>> ++ }
>> ++
>> ++ offset = ELF_ALIGN(doff + descsz);
>> ++ if (doff + descsz > size) {
>> ++ /*
>> ++ * We're past the end of the buffer.
>> ++ */
>> ++ return (offset >= size) ? offset : size;
>> ++ }
>> ++
>> ++ if ((*flags & FLAGS_DID_OS_NOTE) == 0) {
>> ++ if (do_os_note(ms, nbuf, xnh_type, swap,
>> ++ namesz, descsz, noff, doff, flags))
>> ++ return size;
>> ++ }
>> ++
>> ++ if ((*flags & FLAGS_DID_BUILD_ID) == 0) {
>> ++ if (do_bid_note(ms, nbuf, xnh_type, swap,
>> ++ namesz, descsz, noff, doff, flags))
>> ++ return size;
>> ++ }
>> ++
>> ++ if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
>> ++ if (do_pax_note(ms, nbuf, xnh_type, swap,
>> ++ namesz, descsz, noff, doff, flags))
>> ++ return size;
>> ++ }
>> ++
>> ++ if ((*flags & FLAGS_DID_CORE) == 0) {
>> ++ if (do_core_note(ms, nbuf, xnh_type, swap,
>> ++ namesz, descsz, noff, doff, flags, size, clazz))
>> ++ return size;
>> ++ }
>> ++
>> ++ if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
>> ++ if (descsz > 100)
>> ++ descsz = 100;
>> ++ switch (xnh_type) {
>> ++ case NT_NETBSD_VERSION:
>> ++ return size;
>> ++ case NT_NETBSD_MARCH:
>> ++ if (*flags & FLAGS_DID_NETBSD_MARCH)
>> ++ return size;
>> ++ *flags |= FLAGS_DID_NETBSD_MARCH;
>> ++ if (file_printf(ms, ", compiled for: %.*s",
>> ++ (int)descsz, (const char *)&nbuf[doff]) == -1)
>> ++ return size;
>> ++ break;
>> ++ case NT_NETBSD_CMODEL:
>> ++ if (*flags & FLAGS_DID_NETBSD_CMODEL)
>> ++ return size;
>> ++ *flags |= FLAGS_DID_NETBSD_CMODEL;
>> ++ if (file_printf(ms, ", compiler model: %.*s",
>> ++ (int)descsz, (const char *)&nbuf[doff]) == -1)
>> ++ return size;
>> ++ break;
>> ++ default:
>> ++ if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
>> ++ return size;
>> ++ *flags |= FLAGS_DID_NETBSD_UNKNOWN;
>> ++ if (file_printf(ms, ", note=%u", xnh_type) == -1)
>> ++ return size;
>> ++ break;
>> ++ }
>> ++ return size;
>> ++ }
>> ++
>> + return offset;
>> + }
>> +
>> +@@ -896,16 +986,19 @@ static const cap_desc_t cap_desc_386[] = {
>> +
>> + private int
>> + doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
>> int num,
>> +- size_t size, off_t fsize, int *flags, int mach, int strtab)
>> ++ size_t size, off_t fsize, int mach, int strtab, int *flags,
>> ++ uint16_t *notecount)
>> + {
>> + Elf32_Shdr sh32;
>> + Elf64_Shdr sh64;
>> + int stripped = 1;
>> ++ size_t nbadcap = 0;
>> + void *nbuf;
>> + off_t noff, coff, name_off;
>> + uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
>> + uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
>> + char name[50];
>> ++ ssize_t namesize;
>> +
>> + if (size != xsh_sizeof) {
>> + if (file_printf(ms, ", corrupted section header size") == -1)
>> +@@ -914,7 +1007,7 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + }
>> +
>> + /* Read offset of name section to be able to read section names
>> later */
>> +- if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
>> ++ if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) <
>> (ssize_t)xsh_sizeof) {
>> + file_badread(ms);
>> + return -1;
>> + }
>> +@@ -922,15 +1015,15 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> +
>> + for ( ; num; num--) {
>> + /* Read the name of this section. */
>> +- if (pread(fd, name, sizeof(name), name_off + xsh_name) ==
>> -1) {
>> ++ if ((namesize = pread(fd, name, sizeof(name) - 1, name_off
>> + xsh_name)) == -1) {
>> + file_badread(ms);
>> + return -1;
>> + }
>> +- name[sizeof(name) - 1] = '\0';
>> ++ name[namesize] = '\0';
>> + if (strcmp(name, ".debug_info") == 0)
>> + stripped = 0;
>> +
>> +- if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
>> ++ if (pread(fd, xsh_addr, xsh_sizeof, off) <
>> (ssize_t)xsh_sizeof) {
>> + file_badread(ms);
>> + return -1;
>> + }
>> +@@ -945,7 +1038,7 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + stripped = 0;
>> + break;
>> + default:
>> +- if (xsh_offset > fsize) {
>> ++ if (fsize != SIZE_UNKNOWN && xsh_offset > fsize) {
>> + /* Perhaps warn here */
>> + continue;
>> + }
>> +@@ -960,7 +1053,7 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + " for note");
>> + return -1;
>> + }
>> +- if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
>> ++ if (pread(fd, nbuf, xsh_size, xsh_offset) <
>> (ssize_t)xsh_size) {
>> + file_badread(ms);
>> + free(nbuf);
>> + return -1;
>> +@@ -971,7 +1064,7 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + if (noff >= (off_t)xsh_size)
>> + break;
>> + noff = donote(ms, nbuf, (size_t)noff,
>> +- xsh_size, clazz, swap, 4, flags);
>> ++ xsh_size, clazz, swap, 4, flags, notecount);
>> + if (noff == 0)
>> + break;
>> + }
>> +@@ -989,6 +1082,8 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + goto skip;
>> + }
>> +
>> ++ if (nbadcap > 5)
>> ++ break;
>> + if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
>> + file_badseek(ms);
>> + return -1;
>> +@@ -1024,6 +1119,8 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + (unsigned long long)xcap_tag,
>> + (unsigned long long)xcap_val) == -1)
>> + return -1;
>> ++ if (nbadcap++ > 2)
>> ++ coff = xsh_size;
>> + break;
>> + }
>> + }
>> +@@ -1104,7 +1201,8 @@ doshn(struct magic_set *ms, int clazz, int
>> swap, int fd, off_t off, int num,
>> + */
>> + private int
>> + dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t
>> off,
>> +- int num, size_t size, off_t fsize, int *flags, int sh_num)
>> ++ int num, size_t size, off_t fsize, int sh_num, int *flags,
>> ++ uint16_t *notecount)
>> + {
>> + Elf32_Phdr ph32;
>> + Elf64_Phdr ph64;
>> +@@ -1121,7 +1219,7 @@ dophn_exec(struct magic_set *ms, int clazz,
>> int swap, int fd, off_t off,
>> + }
>> +
>> + for ( ; num; num--) {
>> +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
>> ++ if (pread(fd, xph_addr, xph_sizeof, off) <
>> (ssize_t)xph_sizeof) {
>> + file_badread(ms);
>> + return -1;
>> + }
>> +@@ -1137,7 +1235,7 @@ dophn_exec(struct magic_set *ms, int clazz,
>> int swap, int fd, off_t off,
>> + shared_libraries = " (uses shared libs)";
>> + break;
>> + default:
>> +- if (xph_offset > fsize) {
>> ++ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
>> + /* Maybe warn here? */
>> + continue;
>> + }
>> +@@ -1173,7 +1271,7 @@ dophn_exec(struct magic_set *ms, int clazz,
>> int swap, int fd, off_t off,
>> + break;
>> + offset = donote(ms, nbuf, offset,
>> + (size_t)bufsize, clazz, swap, align,
>> +- flags);
>> ++ flags, notecount);
>> + if (offset == 0)
>> + break;
>> + }
>> +@@ -1204,7 +1302,7 @@ file_tryelf(struct magic_set *ms, int fd,
>> const unsigned char *buf,
>> + int flags = 0;
>> + Elf32_Ehdr elf32hdr;
>> + Elf64_Ehdr elf64hdr;
>> +- uint16_t type;
>> ++ uint16_t type, phnum, shnum, notecount;
>> +
>> + if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
>> + return 0;
>> +@@ -1230,7 +1328,10 @@ file_tryelf(struct magic_set *ms, int fd,
>> const unsigned char *buf,
>> + file_badread(ms);
>> + return -1;
>> + }
>> +- fsize = st.st_size;
>> ++ if (S_ISREG(st.st_mode))
>> ++ fsize = st.st_size;
>> ++ else
>> ++ fsize = SIZE_UNKNOWN;
>> +
>> + clazz = buf[EI_CLASS];
>> +
>> +diff --git a/src/softmagic.c b/src/softmagic.c
>> +index dc7928b..b1f5779 100644
>> +--- a/src/softmagic.c
>> ++++ b/src/softmagic.c
>> +@@ -43,11 +43,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.168
>> 2013/05/30 15:53:33 christos Exp $")
>> +
>> +
>> + private int match(struct magic_set *, struct magic *, uint32_t,
>> +- const unsigned char *, size_t, size_t, int, int, int, int, int
>> *, int *,
>> +- int *);
>> ++ const unsigned char *, size_t, size_t, int, int, int, uint16_t,
>> ++ uint16_t *, int *, int *, int *);
>> + private int mget(struct magic_set *, const unsigned char *,
>> +- struct magic *, size_t, size_t, unsigned int, int, int, int,
>> int, int *,
>> +- int *, int *);
>> ++ struct magic *, size_t, size_t, unsigned int, int, int, int,
>> uint16_t,
>> ++ uint16_t *, int *, int *, int *);
>> + private int magiccheck(struct magic_set *, struct magic *);
>> + private int32_t mprint(struct magic_set *, struct magic *);
>> + private int32_t moffset(struct magic_set *, struct magic *);
>> +@@ -69,14 +69,20 @@ private void cvt_64(union VALUETYPE *, const
>> struct magic *);
>> + /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need
>> later */
>> + protected int
>> + file_softmagic(struct magic_set *ms, const unsigned char *buf,
>> size_t nbytes,
>> +- int mode, int text)
>> ++ uint16_t indir_level, uint16_t *name_count, int mode, int text)
>> + {
>> + struct mlist *ml;
>> + int rv, printed_something = 0, need_separator = 0;
>> ++ uint16_t nc;
>> ++
>> ++ if (name_count == NULL) {
>> ++ nc = 0;
>> ++ name_count = &nc;
>> ++ }
>> + for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
>> + if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0,
>> mode,
>> +- text, 0, 0, &printed_something, &need_separator,
>> +- NULL)) != 0)
>> ++ text, 0, indir_level, name_count,
>> ++ &printed_something, &need_separator, NULL)) != 0)
>> + return rv;
>> +
>> + return 0;
>> +@@ -112,8 +118,8 @@ file_softmagic(struct magic_set *ms, const
>> unsigned char *buf, size_t nbytes,
>> + private int
>> + match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
>> + const unsigned char *s, size_t nbytes, size_t offset, int mode,
>> int text,
>> +- int flip, int recursion_level, int *printed_something, int
>> *need_separator,
>> +- int *returnval)
>> ++ int flip, uint16_t indir_level, uint16_t *name_count,
>> ++ int *printed_something, int *need_separator, int *returnval)
>> + {
>> + uint32_t magindex = 0;
>> + unsigned int cont_level = 0;
>> +@@ -150,8 +156,8 @@ match(struct magic_set *ms, struct magic *magic,
>> uint32_t nmagic,
>> +
>> + /* if main entry matches, print it... */
>> + switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
>> +- flip, recursion_level + 1, printed_something,
>> +- need_separator, returnval)) {
>> ++ flip, indir_level, name_count,
>> ++ printed_something, need_separator, returnval)) {
>> + case -1:
>> + return -1;
>> + case 0:
>> +@@ -237,8 +243,8 @@ match(struct magic_set *ms, struct magic *magic,
>> uint32_t nmagic,
>> + }
>> + #endif
>> + switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
>> +- text, flip, recursion_level + 1, printed_something,
>> +- need_separator, returnval)) {
>> ++ text, flip, indir_level, name_count,
>> ++ printed_something, need_separator, returnval)) {
>> + case -1:
>> + return -1;
>> + case 0:
>> +@@ -1120,8 +1126,8 @@ mcopy(struct magic_set *ms, union VALUETYPE
>> *p, int type, int indir,
>> + private int
>> + mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
>> + size_t nbytes, size_t o, unsigned int cont_level, int mode, int
>> text,
>> +- int flip, int recursion_level, int *printed_something,
>> +- int *need_separator, int *returnval)
>> ++ int flip, uint16_t indir_level, uint16_t *name_count,
>> ++ int *printed_something, int *need_separator, int *returnval)
>> + {
>> + uint32_t soffset, offset = ms->offset;
>> + uint32_t count = m->str_range;
>> +@@ -1130,8 +1136,15 @@ mget(struct magic_set *ms, const unsigned
>> char *s, struct magic *m,
>> + union VALUETYPE *p = &ms->ms_value;
>> + struct mlist ml;
>> +
>> +- if (recursion_level >= 20) {
>> +- file_error(ms, 0, "recursion nesting exceeded");
>> ++ if (indir_level >= ms->indir_max) {
>> ++ file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
>> ++ indir_level);
>> ++ return -1;
>> ++ }
>> ++
>> ++ if (*name_count >= ms->name_max) {
>> ++ file_error(ms, 0, "name use count (%hu) exceeded",
>> ++ *name_count);
>> + return -1;
>> + }
>> +
>> +@@ -1141,8 +1154,9 @@ mget(struct magic_set *ms, const unsigned char
>> *s, struct magic *m,
>> +
>> + if ((ms->flags & MAGIC_DEBUG) != 0) {
>> + fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
>> +- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
>> +- nbytes, count);
>> ++ "nbytes=%zu, il=%hu, nc=%hu)\n",
>> ++ m->type, m->flag, offset, o, nbytes,
>> ++ indir_level, *name_count);
>> + mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
>> + #ifndef COMPILE_ONLY
>> + file_mdump(m);
>> +@@ -1711,7 +1725,7 @@ mget(struct magic_set *ms, const unsigned char
>> *s, struct magic *m,
>> + ms->o.buf = NULL;
>> + ms->offset = 0;
>> + rv = file_softmagic(ms, s + offset, nbytes - offset,
>> +- BINTEST, text);
>> ++ indir_level + 1, name_count, BINTEST, text);
>> + if ((ms->flags & MAGIC_DEBUG) != 0)
>> + fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
>> + rbuf = ms->o.buf;
>> +@@ -1730,22 +1744,22 @@ mget(struct magic_set *ms, const unsigned
>> char *s, struct magic *m,
>> + case FILE_USE:
>> + if (nbytes < offset)
>> + return 0;
>> +- sbuf = m->value.s;
>> +- if (*sbuf == '^') {
>> +- sbuf++;
>> ++ rbuf = m->value.s;
>> ++ if (*rbuf == '^') {
>> ++ rbuf++;
>> + flip = !flip;
>> + }
>> +- if (file_magicfind(ms, sbuf, &ml) == -1) {
>> +- file_error(ms, 0, "cannot find entry `%s'", sbuf);
>> ++ if (file_magicfind(ms, rbuf, &ml) == -1) {
>> ++ file_error(ms, 0, "cannot find entry `%s'", rbuf);
>> + return -1;
>> + }
>> +-
>> ++ (*name_count)++;
>> + oneed_separator = *need_separator;
>> + if (m->flag & NOSPACE)
>> + *need_separator = 0;
>> + rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
>> +- mode, text, flip, recursion_level, printed_something,
>> +- need_separator, returnval);
>> ++ mode, text, flip, indir_level, name_count,
>> ++ printed_something, need_separator, returnval);
>> + if (rv != 1)
>> + *need_separator = oneed_separator;
>> + return rv;
>> +--
>> +1.7.9.5
>> +
>> diff --git a/meta/recipes-devtools/file/file_5.16.bb
>> b/meta/recipes-devtools/file/file_5.16.bb
>> index a15d952..f231a55 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"
>> DEPENDS_class-native = "zlib-native"
>>
>> SRC_URI = "ftp://ftp.astron.com/pub/file/file-${PV}.tar.gz \
>> + file://file-CVE-2014-9620-and-CVE-2014-9621.patch \
>> file://dump \
>> file://filesystems"
>>
>>
>
>
More information about the Openembedded-core
mailing list