Subject: Add a limit to the number of times a name/use entries can be used Upstream-Author: Christos Zoulas Date: Fri Nov 28 02:35:05 2014 +0000 Origin: FILE5_20-37-g0056ec3 Last-Update: 2015-01-05 (prequisite for TEMP-0000000-B67840) diff --git a/doc/file.man b/doc/file.man index e4ce958..8ea29ef 100644 --- a/doc/file.man +++ b/doc/file.man @@ -293,10 +293,11 @@ attempt to preserve the access time of files analyzed, to pretend that never read them. .It Fl P , Fl Fl parameter Ar name=value Set various parameter limits. -.Bl -column "indir" "Default" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -offset indent +.Bl -column "namenum" "Default" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -offset indent .It Sy "Name" Ta Sy "Default" Ta Sy "Explanation" .It Li indir Ta 15 Ta recursion limit for indirect magic .It Li name Ta 40 Ta recursion limit for name/use magic +.It Li namenum Ta 30 Ta use count limit for name/use magic .It Li phnum Ta 128 Ta max ELF program sections processed .It Li shnum Ta 32768 Ta max ELF sections processed .El diff --git a/doc/libmagic.man b/doc/libmagic.man index ba06c9f..57ec7dc 100644 --- a/doc/libmagic.man +++ b/doc/libmagic.man @@ -262,6 +262,7 @@ library. .It Sy "Parameter" Ta Sy "Type" Ta Sy "Default" .It Li MAGIC_PARAM_INDIR_RECURSION Ta size_t Ta 15 .It Li MAGIC_PARAM_NAME_RECURSION Ta size_t Ta 40 +.It Li MAGIC_PARAM_NAME_MAX Ta size_t Ta 30 .It Li MAGIC_PARAM_PHNUM_MAX Ta size_t Ta 128 .It Li MAGIC_PARAM_SHNUM_MAX Ta size_t Ta 32768 .El @@ -277,6 +278,10 @@ parameter controls how many levels of recursion will be followed for for name/use calls. .Pp The +.Dv MAGIC_PARAM_NAME_MAX +parameter controls the maximum number of calls for name/use. +.Pp +The .Dv MAGIC_PARAM_PHNUM_MAX parameter controls how many elf program sections will be processed. .Pp diff --git a/src/ascmagic.c b/src/ascmagic.c index 9f4b012..3388682 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), 0, 0, TEXTTEST, text)) == 0) + (size_t)(utf8_end - utf8_buf), 0, 0, NULL, + TEXTTEST, text)) == 0) rv = -1; } diff --git a/src/file.c b/src/file.c index 4bb3102..702a613 100644 --- a/src/file.c +++ b/src/file.c @@ -126,6 +126,7 @@ private struct { } pm[] = { { "indir", MAGIC_PARAM_INDIR_RECURSION, 0 }, { "name", MAGIC_PARAM_NAME_RECURSION, 0 }, + { "namenum", MAGIC_PARAM_NAME_MAX, 0 }, { "phnum", MAGIC_PARAM_PHNUM_MAX, 0 }, { "shnum", MAGIC_PARAM_SHNUM_MAX, 0 }, }; diff --git a/src/file.h b/src/file.h index 237bc4d..6692b3a 100644 --- a/src/file.h +++ b/src/file.h @@ -382,12 +382,14 @@ struct magic_set { union VALUETYPE ms_value; /* either number or string */ uint16_t indir_recursion; uint16_t name_recursion; + uint16_t name_max; uint16_t shnum_max; uint16_t phnum_max; #define FILE_INDIR_RECURSION 15 #define FILE_NAME_RECURSION 40 -#define FILE_ELF_SHNUM 32768 -#define FILE_ELF_PHNUM 128 +#define FILE_NAME_MAX 30 +#define FILE_ELF_SHNUM 32768 +#define FILE_ELF_PHNUM 128 }; /* Type for Unicode characters */ @@ -422,7 +424,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, - uint16_t, uint16_t, int, int); + uint16_t, uint16_t, uint16_t *, int, int); protected struct mlist *file_apprentice(struct magic_set *, const char *, int); protected uint64_t file_signextend(struct magic_set *, struct magic *, uint64_t); diff --git a/src/funcs.c b/src/funcs.c index 88e77ef..91b11fc 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -228,7 +228,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, 0, 0, BINTEST, + if ((m = file_softmagic(ms, ubuf, nb, 0, 0, NULL, BINTEST, looks_text)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "softmagic %d\n", m); diff --git a/src/magic.c b/src/magic.c index aa812df..f2bdae5 100644 --- a/src/magic.c +++ b/src/magic.c @@ -235,6 +235,7 @@ magic_open(int flags) ms->line = 0; ms->indir_recursion = FILE_INDIR_RECURSION; ms->name_recursion = FILE_NAME_RECURSION; + ms->name_max = FILE_NAME_MAX; ms->shnum_max = FILE_ELF_SHNUM; ms->phnum_max = FILE_ELF_PHNUM; return ms; @@ -526,6 +527,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val) case MAGIC_PARAM_NAME_RECURSION: ms->name_recursion = *(const size_t *)val; return 0; + case MAGIC_PARAM_NAME_MAX: + ms->name_max = *(const size_t *)val; + return 0; case MAGIC_PARAM_PHNUM_MAX: ms->phnum_max = *(const size_t *)val; return 0; @@ -548,6 +552,9 @@ magic_getparam(struct magic_set *ms, int param, void *val) case MAGIC_PARAM_NAME_RECURSION: *(size_t *)val = ms->name_recursion; return 0; + case MAGIC_PARAM_NAME_MAX: + *(size_t *)val = ms->name_max; + return 0; case MAGIC_PARAM_PHNUM_MAX: *(size_t *)val = ms->phnum_max; return 0; diff --git a/src/magic.h b/src/magic.h index 20c05c1..c2667cc 100644 --- a/src/magic.h +++ b/src/magic.h @@ -101,8 +101,9 @@ int magic_errno(magic_t); #define MAGIC_PARAM_INDIR_RECURSION 0 #define MAGIC_PARAM_NAME_RECURSION 1 -#define MAGIC_PARAM_PHNUM_MAX 2 -#define MAGIC_PARAM_SHNUM_MAX 3 +#define MAGIC_PARAM_NAME_MAX 2 +#define MAGIC_PARAM_PHNUM_MAX 3 +#define MAGIC_PARAM_SHNUM_MAX 4 int magic_setparam(magic_t, int, const void *); int magic_getparam(magic_t, int, void *); diff --git a/src/softmagic.c b/src/softmagic.c index d507e11..6e94ae9 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -43,9 +43,9 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $") private int match(struct magic_set *, struct magic *, uint32_t, - const unsigned char *, size_t, int, int, uint16_t, uint16_t); + const unsigned char *, size_t, int, int, uint16_t, uint16_t, uint16_t *); private int mget(struct magic_set *, const unsigned char *, - struct magic *, size_t, unsigned int, int, uint16_t, uint16_t); + struct magic *, size_t, unsigned int, int, uint16_t, uint16_t, uint16_t *); 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,13 +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, - uint16_t indir_level, uint16_t name_level, int mode, int text) + uint16_t indir_level, uint16_t name_level, uint16_t *name_count, + int mode, int text) { struct mlist *ml; + uint16_t nc; + if (name_count == NULL) { + nc = 0; + name_count = &nc; + } + int rv; for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode, - text, indir_level, name_level)) != 0) + text, indir_level, name_level, name_count)) != 0) return rv; return 0; @@ -111,7 +118,7 @@ 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, int mode, int text, - uint16_t indir_level, uint16_t name_level) + uint16_t indir_level, uint16_t name_level, uint16_t *name_count) { uint32_t magindex = 0; unsigned int cont_level = 0; @@ -143,7 +150,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, ms->line = m->lineno; /* if main entry matches, print it... */ - switch (mget(ms, s, m, nbytes, cont_level, text, indir_level, name_level)) { + switch (mget(ms, s, m, nbytes, cont_level, text, indir_level, name_level, name_count)) { case -1: return -1; case 0: @@ -226,7 +233,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, continue; } #endif - switch (mget(ms, s, m, nbytes, cont_level, text, indir_level, name_level)) { + switch (mget(ms, s, m, nbytes, cont_level, text, indir_level, name_level, name_count)) { case -1: return -1; case 0: @@ -1042,7 +1049,7 @@ 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, unsigned int cont_level, int text, - uint16_t indir_level, uint16_t name_level) + uint16_t indir_level, uint16_t name_level, uint16_t *name_count) { uint32_t offset = ms->offset; file_pushbuf_t *pb; @@ -1062,6 +1069,12 @@ mget(struct magic_set *ms, const unsigned char *s, return -1; } + if (*name_count >= ms->name_max) { + file_error(ms, 0, "name use count (%hu) exceeded", + *name_count); + return -1; + } + if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, (uint32_t)nbytes, m) == -1) return -1; @@ -1625,7 +1638,7 @@ mget(struct magic_set *ms, const unsigned char *s, return -1; rv = file_softmagic(ms, s + offset, nbytes - offset, - indir_level + 1, name_level, BINTEST, text); + indir_level + 1, name_level, name_count, BINTEST, text); if ((ms->flags & MAGIC_DEBUG) != 0) fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);