Upstream-Author: Christos Zoulas Date: Wed Jan 8 22:22:54 2014 +0000 Last-Update: 2014-03-05 Upstream-Commit: 447558595a3650db2886cd2f416ad0beba965801 70c65d2e1841491f59168db1f905e8b14083fb1c Description: PR/313: Aaron Reffett: Check properly for exceeding the offset. . off by one in out of bounds calculations (Jan Kaluza) . CVE-2014-2270 Backport for 5.04: Christoph Biedl --- a/src/softmagic.c +++ b/src/softmagic.c @@ -60,6 +60,7 @@ 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))) /* * softmagic - lookup one file in parsed, in-memory copy of database * Passed the name and FILE * of one file to be typed. @@ -1085,7 +1086,7 @@ } switch (m->in_type) { case FILE_BYTE: - if (nbytes < (offset + 1)) + if (OFFSET_OOB(nbytes, offset, 1)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1120,7 +1121,7 @@ offset = ~offset; break; case FILE_BESHORT: - if (nbytes < (offset + 2)) + if (OFFSET_OOB(nbytes, offset, 2)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1172,7 +1173,7 @@ offset = ~offset; break; case FILE_LESHORT: - if (nbytes < (offset + 2)) + if (OFFSET_OOB(nbytes, offset, 2)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1224,7 +1225,7 @@ offset = ~offset; break; case FILE_SHORT: - if (nbytes < (offset + 2)) + if (OFFSET_OOB(nbytes, offset, 2)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1261,7 +1262,7 @@ break; case FILE_BELONG: case FILE_BEID3: - if (nbytes < (offset + 4)) + if (OFFSET_OOB(nbytes, offset, 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1332,7 +1333,7 @@ break; case FILE_LELONG: case FILE_LEID3: - if (nbytes < (offset + 4)) + if (OFFSET_OOB(nbytes, offset, 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1402,7 +1403,7 @@ offset = ~offset; break; case FILE_MELONG: - if (nbytes < (offset + 4)) + if (OFFSET_OOB(nbytes, offset, 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1472,7 +1473,7 @@ offset = ~offset; break; case FILE_LONG: - if (nbytes < (offset + 4)) + if (OFFSET_OOB(nbytes, offset, 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { @@ -1539,14 +1540,14 @@ /* Verify we have enough data to match magic type */ switch (m->type) { case FILE_BYTE: - if (nbytes < (offset + 1)) /* should alway be true */ + if (OFFSET_OOB(nbytes, offset, 1)) return 0; break; case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: - if (nbytes < (offset + 2)) + if (OFFSET_OOB(nbytes, offset, 2)) return 0; break; @@ -1565,26 +1566,26 @@ case FILE_FLOAT: case FILE_BEFLOAT: case FILE_LEFLOAT: - if (nbytes < (offset + 4)) + if (OFFSET_OOB(nbytes, offset, 4)) return 0; break; case FILE_DOUBLE: case FILE_BEDOUBLE: case FILE_LEDOUBLE: - if (nbytes < (offset + 8)) + if (OFFSET_OOB(nbytes, offset, 8)) return 0; break; case FILE_STRING: case FILE_PSTRING: case FILE_SEARCH: - if (nbytes < (offset + m->vallen)) + if (OFFSET_OOB(nbytes, offset, m->vallen)) return 0; break; case FILE_REGEX: - if (nbytes < offset) + if (OFFSET_OOB(nbytes, offset, 0)) return 0; break; @@ -1594,7 +1595,7 @@ if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && file_printf(ms, "%s", m->desc) == -1) return -1; - if (nbytes < offset) + if (OFFSET_OOB(nbytes, offset, 0)) return 0; return file_softmagic(ms, s + offset, nbytes - offset, recursion_level, BINTEST);