123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- Subject: file does not properly restrict the amount of data read during a regex search
- ID: CVE-2014-3538
- Author: Christos Zoulas <christos@zoulas.com>
- Date: Tue Jun 3 19:01:34 2014 +0000
- Origin:
- commit 4a284c89d6ef11aca34da65da7d673050a5ea320
- Debian-Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
- Comment:
- Taken from the fix in php5 (5.4.4-14+deb7u13), with minor corrections.
- Last-Update: 2014-09-07
- * Enforce limit of 8K on regex searches that have no limits
- * Allow the l modifier for regex to mean line count. Default
- to byte count. If line count is specified, assume a max
- of 80 characters per line to limit the byte count.
- * Don't allow conversions to be used for dates, allowing
- the mask field to be used as an offset.
- * Bump the version of the magic format so that regex changes
- are visible.
- --- a/src/softmagic.c
- +++ b/src/softmagic.c
- @@ -51,7 +51,7 @@
- private int32_t moffset(struct magic_set *, struct magic *);
- private void mdebug(uint32_t, const char *, size_t);
- private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
- - const unsigned char *, uint32_t, size_t, size_t);
- + const unsigned char *, uint32_t, size_t, struct magic *);
- private int mconvert(struct magic_set *, struct magic *);
- private int print_sep(struct magic_set *, int);
- private int handle_annotation(struct magic_set *, struct magic *);
- @@ -918,7 +918,7 @@
-
- private int
- mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
- - const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
- + const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
- {
- /*
- * Note: FILE_SEARCH and FILE_REGEX do not actually copy
- @@ -938,15 +938,24 @@
- const char *last; /* end of search region */
- const char *buf; /* start of search region */
- const char *end;
- - size_t lines;
- + size_t lines, linecnt, bytecnt;
-
- + linecnt = m->str_range;
- + bytecnt = linecnt * 80;
- +
- + if (bytecnt == 0) {
- + bytecnt = 8192;
- + }
- + if (bytecnt > nbytes) {
- + bytecnt = nbytes;
- + }
- if (s == NULL) {
- ms->search.s_len = 0;
- ms->search.s = NULL;
- return 0;
- }
- buf = RCAST(const char *, s) + offset;
- - end = last = RCAST(const char *, s) + nbytes;
- + end = last = RCAST(const char *, s) + bytecnt;
- /* mget() guarantees buf <= last */
- for (lines = linecnt, b = buf; lines && b < end &&
- ((b = CAST(const char *,
- @@ -959,7 +968,7 @@
- b++;
- }
- if (lines)
- - last = RCAST(const char *, s) + nbytes;
- + last = RCAST(const char *, s) + bytecnt;
-
- ms->search.s = buf;
- ms->search.s_len = last - buf;
- @@ -1032,7 +1041,6 @@
- int recursion_level)
- {
- uint32_t offset = ms->offset;
- - uint32_t count = m->str_range;
- union VALUETYPE *p = &ms->ms_value;
-
- if (recursion_level >= 20) {
- @@ -1040,7 +1048,8 @@
- return -1;
- }
-
- - if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
- + if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset,
- + (uint32_t)nbytes, m) == -1)
- return -1;
-
- if ((ms->flags & MAGIC_DEBUG) != 0) {
- @@ -1527,7 +1536,7 @@
- if (m->flag & INDIROFFADD) {
- offset += ms->c.li[cont_level-1].off;
- }
- - if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
- + if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
- return -1;
- ms->offset = offset;
-
|