]> granicus.if.org Git - file/commitdiff
add a limit to the number of times a name/use entries can be used.
authorChristos Zoulas <christos@zoulas.com>
Fri, 28 Nov 2014 02:35:05 +0000 (02:35 +0000)
committerChristos Zoulas <christos@zoulas.com>
Fri, 28 Nov 2014 02:35:05 +0000 (02:35 +0000)
doc/file.man
doc/libmagic.man
src/apprentice.c
src/ascmagic.c
src/file.c
src/file.h
src/funcs.c
src/magic.c
src/magic.h.in
src/softmagic.c

index a9196529c4a821582b3d0e0dc73b47fc418352b3..9378b5b3b46ecca5b66164be2b3b1d1990edaf32 100644 (file)
@@ -1,4 +1,4 @@
-.\" $File: file.man,v 1.108 2014/11/27 23:42:58 christos Exp $
+.\" $File: file.man,v 1.109 2014/11/28 02:35:05 christos Exp $
 .Dd November 27, 2014
 .Dt FILE __CSECTION__
 .Os
@@ -306,10 +306,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
index 886f96951456accd558e6300f289fc7bcd012a1f..34a36c93a6fdd631b7f9dc1f4418a258589ad3f5 100644 (file)
@@ -1,4 +1,4 @@
-.\" $File: libmagic.man,v 1.31 2014/11/27 23:42:58 christos Exp $
+.\" $File: libmagic.man,v 1.32 2014/11/28 02:35:05 christos Exp $
 .\"
 .\" Copyright (c) Christos Zoulas 2003.
 .\" All Rights Reserved.
@@ -284,6 +284,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
@@ -299,6 +300,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
index f45081796f294660552045513a18055fdba8b91e..1e93df786ce2448084d2490020632029e226580f 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.225 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.226 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -526,6 +526,7 @@ file_ms_alloc(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;
index 20173a961d418e393c021921b8cefd0726fcd8eb..8424c432d903482f3932d39c72f64135b3227123 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.89 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.90 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -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;
        }
 
index f7bc4082d37106d91837e37697ddb6319c5ebcb2..e9b4cd81ab7d495d837f66ea867a536db021e365 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: file.c,v 1.157 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.158 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -123,6 +123,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 },
 };
index 196a3b28b934a094f4e3338ca1666f09ede4e77f..a0684d65a570417f4523f6cb771884d180af893a 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.158 2014/11/27 23:42:58 christos Exp $
+ * @(#)$File: file.h,v 1.159 2014/11/28 02:35:05 christos Exp $
  */
 
 #ifndef __file_h__
@@ -403,12 +403,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 */
@@ -448,7 +450,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 int file_apprentice(struct magic_set *, const char *, int);
 protected int buffer_apprentice(struct magic_set *, struct magic **,
     size_t *, size_t);
index a46a4c3323a543d444e147602d3e0115dd46344b..0b2f6e5334b7664244197d048a40a96f200f324a 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.75 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.76 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -227,7 +227,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);
index 5c8d54b9a1469ca9dfffe7cc91c067c537bb134c..83af775905cff4df44f84990ea03421fc23a8055 100644 (file)
@@ -33,7 +33,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: magic.c,v 1.87 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.88 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -547,6 +547,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;
@@ -569,6 +572,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;
index ddd9253572e00a2e71918a80462329e306d7effb..3b8bc1e85ccc4de172d1a87f54c1357fc5fafe9f 100644 (file)
@@ -105,8 +105,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 *);
index 9d9c943a2ee49d8bde5db895fb0707c6e540b464..0ae446719884c4d54d592381cc8e6e1013a1f2c5 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.200 2014/11/27 23:42:58 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.201 2014/11/28 02:35:05 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -44,10 +44,10 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.200 2014/11/27 23:42:58 christos Exp $")
 
 private int match(struct magic_set *, struct magic *, uint32_t,
     const unsigned char *, size_t, size_t, int, int, int, uint16_t, uint16_t,
-    int *, int *, int *);
+    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, uint16_t,
-    uint16_t, 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 *);
@@ -71,15 +71,22 @@ 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;
        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, indir_level, name_level, &printed_something,
-                   &need_separator, NULL)) != 0)
+                   text, 0, indir_level, name_level, name_count,
+                   &printed_something, &need_separator, NULL)) != 0)
                        return rv;
 
        return 0;
@@ -134,8 +141,8 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
 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, uint16_t indir_level, uint16_t name_level, int *printed_something,
-    int *need_separator, int *returnval)
+    int flip, uint16_t indir_level, uint16_t name_level, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval)
 {
        uint32_t magindex = 0;
        unsigned int cont_level = 0;
@@ -172,8 +179,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, indir_level, name_level, printed_something,
-                   need_separator, returnval)) {
+                   flip, indir_level, name_level, name_count,
+                   printed_something, need_separator, returnval)) {
                case -1:
                        return -1;
                case 0:
@@ -261,7 +268,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                        }
 #endif
                        switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
-                           text, flip, indir_level, name_level,
+                           text, flip, indir_level, name_level, name_count,
                            printed_something, need_separator, returnval)) {
                        case -1:
                                return -1;
@@ -1215,8 +1222,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, uint16_t indir_level, uint16_t name_level, int *printed_something,
-    int *need_separator, int *returnval)
+    int flip, uint16_t indir_level, uint16_t name_level, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval)
 {
        uint32_t offset = ms->offset;
        uint32_t lhs;
@@ -1238,14 +1245,22 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
                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, (uint32_t)(offset + o),
            (uint32_t)nbytes, m) == -1)
                return -1;
 
        if ((ms->flags & MAGIC_DEBUG) != 0) {
                fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%"
-                   SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT "u)\n",
-                   m->type, m->flag, offset, o, nbytes);
+                   SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
+                   "u, il=%hu, nl=%hu nc=%hu)\n",
+                   m->type, m->flag, offset, o, nbytes,
+                   indir_level, name_level, *name_count);
                mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
 #ifndef COMPILE_ONLY
                file_mdump(m);
@@ -1686,7 +1701,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
                        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);
@@ -1721,12 +1736,12 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
                        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, indir_level, name_level + 1,
+                   mode, text, flip, indir_level, name_level + 1, name_count,
                    printed_something, need_separator, returnval);
                if (rv != 1)
                    *need_separator = oneed_separator;