Skip to content

Commit 7f5f460

Browse files
committed
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.
1 parent aea4116 commit 7f5f460

File tree

2 files changed

+17
-23
lines changed

2 files changed

+17
-23
lines changed

ext/fileinfo/libmagic/apprentice.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,18 +2567,19 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
25672567
return -1;
25682568
}
25692569
if (m->type == FILE_REGEX) {
2570-
/* XXX do we need this? */
2571-
/*zval pattern;
2570+
zval pattern;
25722571
int options = 0;
25732572
pcre_cache_entry *pce;
25742573

25752574
convert_libmagic_pattern(&pattern, m->value.s, strlen(m->value.s), options);
25762575

25772576
if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) {
2577+
zval_dtor(&pattern);
25782578
return -1;
25792579
}
2580+
zval_dtor(&pattern);
25802581

2581-
return 0;*/
2582+
return 0;
25822583
}
25832584
return 0;
25842585
default:

ext/fileinfo/libmagic/softmagic.c

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,28 +1268,21 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
12681268
return 0;
12691269
}
12701270

1271-
/* bytecnt checks are to be kept for PHP, see cve-2014-3538.
1272-
PCRE might get stuck if the input buffer is too big. */
1273-
linecnt = m->str_range;
1274-
bytecnt = linecnt * 80;
1275-
1276-
if (bytecnt == 0) {
1277-
bytecnt = 1 << 14;
1271+
if (m->str_flags & REGEX_LINE_COUNT) {
1272+
linecnt = m->str_range;
1273+
bytecnt = linecnt * 80;
1274+
} else {
1275+
linecnt = 0;
1276+
bytecnt = m->str_range;
12781277
}
12791278

1280-
if (bytecnt > nbytes) {
1281-
bytecnt = nbytes;
1282-
}
1283-
if (offset > bytecnt) {
1284-
offset = bytecnt;
1285-
}
1286-
if (s == NULL) {
1287-
ms->search.s_len = 0;
1288-
ms->search.s = NULL;
1289-
return 0;
1290-
}
1279+
if (bytecnt == 0 || bytecnt > nbytes - offset)
1280+
bytecnt = nbytes - offset;
1281+
if (bytecnt > ms->regex_max)
1282+
bytecnt = ms->regex_max;
1283+
12911284
buf = RCAST(const char *, s) + offset;
1292-
end = last = RCAST(const char *, s) + bytecnt;
1285+
end = last = RCAST(const char *, s) + bytecnt + offset;
12931286
/* mget() guarantees buf <= last */
12941287
for (lines = linecnt, b = buf; lines && b < end &&
12951288
((b = CAST(const char *,
@@ -1302,7 +1295,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
13021295
b++;
13031296
}
13041297
if (lines)
1305-
last = RCAST(const char *, s) + bytecnt;
1298+
last = end;
13061299

13071300
ms->search.s = buf;
13081301
ms->search.s_len = last - buf;

0 commit comments

Comments
 (0)