|
@@ -0,0 +1,103 @@
|
|
|
+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;
|
|
|
+
|