summaryrefslogtreecommitdiff
path: root/ext/fileinfo/libmagic
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2018-11-04 13:11:28 +0100
committerAnatol Belski <ab@php.net>2018-11-04 13:11:28 +0100
commit7f5f46013b8a37bab6b378903aace5da9ce8dc5e (patch)
tree12238d8d4be505abba7b6074a03f6fddb466380b /ext/fileinfo/libmagic
parentaea411657ee20572f8268060a4afa73bc3795497 (diff)
downloadphp-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.c7
-rw-r--r--ext/fileinfo/libmagic/softmagic.c33
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;