diff options
author | Anatol Belski <ab@php.net> | 2018-11-04 13:11:28 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2018-11-04 13:11:28 +0100 |
commit | 7f5f46013b8a37bab6b378903aace5da9ce8dc5e (patch) | |
tree | 12238d8d4be505abba7b6074a03f6fddb466380b /ext/fileinfo/libmagic | |
parent | aea411657ee20572f8268060a4afa73bc3795497 (diff) | |
download | php-git-7f5f46013b8a37bab6b378903aace5da9ce8dc5e.tar.gz |
Rework places in libmagic regarding previous CVE-2014-3538 fixes
CVE-2014-3538 was fixed upstream, but the old patch was still kept in
the PHP port. This patch causes performance regressions when PCRE JIT is
not enabled. This is fixed by applying the relevant original code from
the newer libmagic, which makes the old patch obsolete as the
CVE-2014-3538 tests still pass.
Diffstat (limited to 'ext/fileinfo/libmagic')
-rw-r--r-- | ext/fileinfo/libmagic/apprentice.c | 7 | ||||
-rw-r--r-- | ext/fileinfo/libmagic/softmagic.c | 33 |
2 files changed, 17 insertions, 23 deletions
diff --git a/ext/fileinfo/libmagic/apprentice.c b/ext/fileinfo/libmagic/apprentice.c index 2035544c5c..94e4302d61 100644 --- a/ext/fileinfo/libmagic/apprentice.c +++ b/ext/fileinfo/libmagic/apprentice.c @@ -2567,18 +2567,19 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) return -1; } if (m->type == FILE_REGEX) { - /* XXX do we need this? */ - /*zval pattern; + zval pattern; int options = 0; pcre_cache_entry *pce; convert_libmagic_pattern(&pattern, m->value.s, strlen(m->value.s), options); if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) { + zval_dtor(&pattern); return -1; } + zval_dtor(&pattern); - return 0;*/ + return 0; } return 0; default: diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index b25f48f1e4..e9d45ff2b9 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -1268,28 +1268,21 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, return 0; } - /* bytecnt checks are to be kept for PHP, see cve-2014-3538. - PCRE might get stuck if the input buffer is too big. */ - linecnt = m->str_range; - bytecnt = linecnt * 80; - - if (bytecnt == 0) { - bytecnt = 1 << 14; + if (m->str_flags & REGEX_LINE_COUNT) { + linecnt = m->str_range; + bytecnt = linecnt * 80; + } else { + linecnt = 0; + bytecnt = m->str_range; } - if (bytecnt > nbytes) { - bytecnt = nbytes; - } - if (offset > bytecnt) { - offset = bytecnt; - } - if (s == NULL) { - ms->search.s_len = 0; - ms->search.s = NULL; - return 0; - } + if (bytecnt == 0 || bytecnt > nbytes - offset) + bytecnt = nbytes - offset; + if (bytecnt > ms->regex_max) + bytecnt = ms->regex_max; + buf = RCAST(const char *, s) + offset; - end = last = RCAST(const char *, s) + bytecnt; + end = last = RCAST(const char *, s) + bytecnt + offset; /* mget() guarantees buf <= last */ for (lines = linecnt, b = buf; lines && b < end && ((b = CAST(const char *, @@ -1302,7 +1295,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, b++; } if (lines) - last = RCAST(const char *, s) + bytecnt; + last = end; ms->search.s = buf; ms->search.s_len = last - buf; |