|
@@ -1,253 +0,0 @@
|
|
-Subject: PR/479: Protect against 0-divide and offset out of bounds reads
|
|
|
|
-Origin: FILE5_25-2-gde23336
|
|
|
|
-Upstream-Author: Christos Zoulas <christos@zoulas.com>
|
|
|
|
-Date: Wed Sep 16 18:25:23 2015 +0000
|
|
|
|
-
|
|
|
|
---- a/src/softmagic.c
|
|
|
|
-+++ b/src/softmagic.c
|
|
|
|
-@@ -57,10 +57,10 @@
|
|
|
|
- private int mconvert(struct magic_set *, struct magic *, int);
|
|
|
|
- private int print_sep(struct magic_set *, int);
|
|
|
|
- private int handle_annotation(struct magic_set *, struct magic *);
|
|
|
|
--private void cvt_8(union VALUETYPE *, const struct magic *);
|
|
|
|
--private void cvt_16(union VALUETYPE *, const struct magic *);
|
|
|
|
--private void cvt_32(union VALUETYPE *, const struct magic *);
|
|
|
|
--private void cvt_64(union VALUETYPE *, const struct magic *);
|
|
|
|
-+private int cvt_8(union VALUETYPE *, const struct magic *);
|
|
|
|
-+private int cvt_16(union VALUETYPE *, const struct magic *);
|
|
|
|
-+private int cvt_32(union VALUETYPE *, const struct magic *);
|
|
|
|
-+private int cvt_64(union VALUETYPE *, const struct magic *);
|
|
|
|
-
|
|
|
|
- #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
|
|
|
|
- #define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
|
|
|
|
-@@ -858,37 +858,45 @@
|
|
|
|
- p->fld *= cast m->num_mask; \
|
|
|
|
- break; \
|
|
|
|
- case FILE_OPDIVIDE: \
|
|
|
|
-+ if (cast m->num_mask == 0) \
|
|
|
|
-+ return -1; \
|
|
|
|
- p->fld /= cast m->num_mask; \
|
|
|
|
- break; \
|
|
|
|
- case FILE_OPMODULO: \
|
|
|
|
-+ if (cast m->num_mask == 0) \
|
|
|
|
-+ return -1; \
|
|
|
|
- p->fld %= cast m->num_mask; \
|
|
|
|
- break; \
|
|
|
|
- } \
|
|
|
|
- if (m->mask_op & FILE_OPINVERSE) \
|
|
|
|
- p->fld = ~p->fld \
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_8(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT(b, (uint8_t));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_16(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT(h, (uint16_t));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_32(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT(l, (uint32_t));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_64(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT(q, (uint64_t));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- #define DO_CVT2(fld, cast) \
|
|
|
|
-@@ -904,20 +912,24 @@
|
|
|
|
- p->fld *= cast m->num_mask; \
|
|
|
|
- break; \
|
|
|
|
- case FILE_OPDIVIDE: \
|
|
|
|
-+ if (cast m->num_mask == 0) \
|
|
|
|
-+ return -1; \
|
|
|
|
- p->fld /= cast m->num_mask; \
|
|
|
|
- break; \
|
|
|
|
- } \
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_float(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT2(f, (float));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
--private void
|
|
|
|
-+private int
|
|
|
|
- cvt_double(union VALUETYPE *p, const struct magic *m)
|
|
|
|
- {
|
|
|
|
- DO_CVT2(d, (double));
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
-@@ -933,21 +945,25 @@
|
|
|
|
-
|
|
|
|
- switch (type = cvt_flip(m->type, flip)) {
|
|
|
|
- case FILE_BYTE:
|
|
|
|
-- cvt_8(p, m);
|
|
|
|
-+ if (cvt_8(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_SHORT:
|
|
|
|
-- cvt_16(p, m);
|
|
|
|
-+ if (cvt_16(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LONG:
|
|
|
|
- case FILE_DATE:
|
|
|
|
- case FILE_LDATE:
|
|
|
|
-- cvt_32(p, m);
|
|
|
|
-+ if (cvt_32(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_QUAD:
|
|
|
|
- case FILE_QDATE:
|
|
|
|
- case FILE_QLDATE:
|
|
|
|
- case FILE_QWDATE:
|
|
|
|
-- cvt_64(p, m);
|
|
|
|
-+ if (cvt_64(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_STRING:
|
|
|
|
- case FILE_BESTRING16:
|
|
|
|
-@@ -979,65 +995,78 @@
|
|
|
|
- }
|
|
|
|
- case FILE_BESHORT:
|
|
|
|
- p->h = (short)BE16(p);
|
|
|
|
-- cvt_16(p, m);
|
|
|
|
-+ if (cvt_16(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_BELONG:
|
|
|
|
- case FILE_BEDATE:
|
|
|
|
- case FILE_BELDATE:
|
|
|
|
- p->l = (int32_t)BE32(p);
|
|
|
|
-- cvt_32(p, m);
|
|
|
|
-+ if (cvt_32(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_BEQUAD:
|
|
|
|
- case FILE_BEQDATE:
|
|
|
|
- case FILE_BEQLDATE:
|
|
|
|
- case FILE_BEQWDATE:
|
|
|
|
- p->q = (uint64_t)BE64(p);
|
|
|
|
-- cvt_64(p, m);
|
|
|
|
-+ if (cvt_64(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LESHORT:
|
|
|
|
- p->h = (short)LE16(p);
|
|
|
|
-- cvt_16(p, m);
|
|
|
|
-+ if (cvt_16(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LELONG:
|
|
|
|
- case FILE_LEDATE:
|
|
|
|
- case FILE_LELDATE:
|
|
|
|
- p->l = (int32_t)LE32(p);
|
|
|
|
-- cvt_32(p, m);
|
|
|
|
-+ if (cvt_32(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LEQUAD:
|
|
|
|
- case FILE_LEQDATE:
|
|
|
|
- case FILE_LEQLDATE:
|
|
|
|
- case FILE_LEQWDATE:
|
|
|
|
- p->q = (uint64_t)LE64(p);
|
|
|
|
-- cvt_64(p, m);
|
|
|
|
-+ if (cvt_64(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_MELONG:
|
|
|
|
- case FILE_MEDATE:
|
|
|
|
- case FILE_MELDATE:
|
|
|
|
- p->l = (int32_t)ME32(p);
|
|
|
|
-- cvt_32(p, m);
|
|
|
|
-+ if (cvt_32(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_FLOAT:
|
|
|
|
-- cvt_float(p, m);
|
|
|
|
-+ if (cvt_float(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_BEFLOAT:
|
|
|
|
- p->l = BE32(p);
|
|
|
|
-- cvt_float(p, m);
|
|
|
|
-+ if (cvt_float(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LEFLOAT:
|
|
|
|
- p->l = LE32(p);
|
|
|
|
-- cvt_float(p, m);
|
|
|
|
-+ if (cvt_float(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_DOUBLE:
|
|
|
|
-- cvt_double(p, m);
|
|
|
|
-+ if (cvt_double(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_BEDOUBLE:
|
|
|
|
- p->q = BE64(p);
|
|
|
|
-- cvt_double(p, m);
|
|
|
|
-+ if (cvt_double(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_LEDOUBLE:
|
|
|
|
- p->q = LE64(p);
|
|
|
|
-- cvt_double(p, m);
|
|
|
|
-+ if (cvt_double(p, m) == -1)
|
|
|
|
-+ goto out;
|
|
|
|
- return 1;
|
|
|
|
- case FILE_REGEX:
|
|
|
|
- case FILE_SEARCH:
|
|
|
|
-@@ -1050,6 +1079,9 @@
|
|
|
|
- file_magerror(ms, "invalid type %d in mconvert()", m->type);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-+out:
|
|
|
|
-+ file_magerror(ms, "zerodivide in mconvert()");
|
|
|
|
-+ return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-@@ -1066,6 +1098,12 @@
|
|
|
|
- mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
|
|
- const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
|
|
|
|
- {
|
|
|
|
-+ if (offset >= nbytes) {
|
|
|
|
-+ file_magerror(ms,
|
|
|
|
-+ "offset in magic %u greater than buffer size %zu",
|
|
|
|
-+ offset, nbytes);
|
|
|
|
-+ return -1;
|
|
|
|
-+ }
|
|
|
|
- /*
|
|
|
|
- * Note: FILE_SEARCH and FILE_REGEX do not actually copy
|
|
|
|
- * anything, but setup pointers into the source
|
|
|
|
-@@ -1230,6 +1268,8 @@
|
|
|
|
- if (m->in_op & FILE_OPINDIRECT) {
|
|
|
|
- const union VALUETYPE *q = CAST(const union VALUETYPE *,
|
|
|
|
- ((const void *)(s + offset + off)));
|
|
|
|
-+ if (OFFSET_OOB(offset + off, nbytes, sizeof(*q)))
|
|
|
|
-+ return 0;
|
|
|
|
- switch (cvt_flip(m->in_type, flip)) {
|
|
|
|
- case FILE_BYTE:
|
|
|
|
- off = q->b;
|
|
|