123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- Subject: Reduce recursion level from 20 to 10 and make a symbolic constant for it. (...)
- ID: CVE-2014-8117
- Upstream-Author: Christos Zoulas <christos@zoulas.com>
- Date: Sun Nov 23 13:54:27 2014 +0000
- Origin: FILE5_20-29-g6f737dd
- Last-Update: 2015-01-05
- - reduce recursion level from 20 to 10 and make a symbolic constant for it.
- - pull out the guts of saving and restoring the output buffer into functions
- and take care not to overwrite the error message if an error happened.
- diff --git a/src/file.h b/src/file.h
- index de262b2..6f61643 100644
- --- a/src/file.h
- +++ b/src/file.h
- @@ -444,6 +444,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/funcs.c b/src/funcs.c
- index 0d645eb..04bab02 100644
- --- a/src/funcs.c
- +++ b/src/funcs.c
- @@ -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/softmagic.c b/src/softmagic.c
- index 72eae4b..0ace99f 100644
- --- a/src/softmagic.c
- +++ b/src/softmagic.c
- @@ -61,6 +61,9 @@ private void cvt_32(union VALUETYPE *, const struct magic *);
- private void cvt_64(union VALUETYPE *, const struct magic *);
-
- #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
- +
- +#define MAX_RECURSION_LEVEL 10
- +
- /*
- * softmagic - lookup one file in parsed, in-memory copy of database
- * Passed the name and FILE * of one file to be typed.
- @@ -1044,11 +1047,12 @@ mget(struct magic_set *ms, const unsigned char *s,
- int recursion_level)
- {
- uint32_t offset = ms->offset;
- + file_pushbuf_t *pb;
- int rv;
- - char *sbuf, *rbuf;
- + char *rbuf;
- union VALUETYPE *p = &ms->ms_value;
-
- - if (recursion_level >= 20) {
- + if (recursion_level >= MAX_RECURSION_LEVEL) {
- file_error(ms, 0, "recursion nesting exceeded");
- return -1;
- }
- @@ -1611,15 +1615,21 @@ mget(struct magic_set *ms, const unsigned char *s,
- return 0;
- if (nbytes < offset)
- return 0;
- - sbuf = ms->o.buf;
- - ms->o.buf = NULL;
- +
- + if ((pb = file_push_buffer(ms)) == NULL)
- + return -1;
- +
- rv = file_softmagic(ms, s + offset, nbytes - offset,
- recursion_level, BINTEST, text);
- +
- if ((ms->flags & MAGIC_DEBUG) != 0)
- fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
- +
- + rbuf = file_pop_buffer(ms, pb);
- + if (rbuf == NULL)
- + return -1;
- +
- if (rv == 1) {
- - rbuf = ms->o.buf;
- - ms->o.buf = sbuf;
- if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
- file_printf(ms, m->desc, offset) == -1) {
- free(rbuf);
- @@ -1629,9 +1639,8 @@ mget(struct magic_set *ms, const unsigned char *s,
- free(rbuf);
- return -1;
- }
- - free(rbuf);
- - } else
- - ms->o.buf = sbuf;
- + }
- + free(rbuf);
- return rv;
-
- case FILE_DEFAULT: /* nothing to check */
|