|
|
d2399a |
From eeaec70758bfc0c0e2c0f8944c8dbeae02866206 Mon Sep 17 00:00:00 2001
|
|
|
d2399a |
From: Stanislav Malyshev <stas@php.net>
|
|
|
d2399a |
Date: Mon, 4 Aug 2014 00:01:57 -0700
|
|
|
d2399a |
Subject: [PATCH] Fix bug #67705 (extensive backtracking in rule regular
|
|
|
d2399a |
expression)
|
|
|
d2399a |
|
|
|
d2399a |
---
|
|
|
d2399a |
NEWS | 4 +++
|
|
|
d2399a |
ext/fileinfo/data_file.c | 2 +-
|
|
|
d2399a |
ext/fileinfo/libmagic/softmagic.c | 29 +++++++++++-------
|
|
|
d2399a |
ext/fileinfo/magicdata.patch | 62 +++++++++++++++++++++++++++++++++------
|
|
|
d2399a |
4 files changed, 76 insertions(+), 21 deletions(-)
|
|
|
d2399a |
|
|
|
d2399a |
diff --git a/ext/fileinfo/data_file.c b/ext/fileinfo/data_file.c
|
|
|
d2399a |
index fba4edd..15e0fa6 100644
|
|
|
d2399a |
--- a/ext/fileinfo/data_file.c
|
|
|
d2399a |
+++ b/ext/fileinfo/data_file.c
|
|
|
d2399a |
@@ -115198,7 +115198,7 @@ const unsigned char php_magic_database[2606480] = {
|
|
|
d2399a |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
0x00, 0x00, 0x40, 0x00, 0x3D, 0x1B, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
-0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
0x5E, 0x5C, 0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x5C,
|
|
|
d2399a |
0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x5B, 0x7B, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
d2399a |
diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c
|
|
|
d2399a |
index 01e4977..7e0c856 100644
|
|
|
d2399a |
--- a/ext/fileinfo/libmagic/softmagic.c
|
|
|
d2399a |
+++ b/ext/fileinfo/libmagic/softmagic.c
|
|
|
d2399a |
@@ -58,7 +58,7 @@ private int32_t mprint(struct magic_set *, struct magic *);
|
|
|
d2399a |
private int32_t moffset(struct magic_set *, struct magic *);
|
|
|
d2399a |
private void mdebug(uint32_t, const char *, size_t);
|
|
|
d2399a |
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
|
|
|
d2399a |
- const unsigned char *, uint32_t, size_t, size_t);
|
|
|
d2399a |
+ const unsigned char *, uint32_t, size_t, struct magic *);
|
|
|
d2399a |
private int mconvert(struct magic_set *, struct magic *, int);
|
|
|
d2399a |
private int print_sep(struct magic_set *, int);
|
|
|
d2399a |
private int handle_annotation(struct magic_set *, struct magic *);
|
|
|
d2399a |
@@ -1003,7 +1003,7 @@ mdebug(uint32_t offset, const char *str, size_t len)
|
|
|
d2399a |
|
|
|
d2399a |
private int
|
|
|
d2399a |
mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
|
d2399a |
- const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
|
|
|
d2399a |
+ const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
|
|
|
d2399a |
{
|
|
|
d2399a |
/*
|
|
|
d2399a |
* Note: FILE_SEARCH and FILE_REGEX do not actually copy
|
|
|
d2399a |
@@ -1023,15 +1023,24 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
|
d2399a |
const char *last; /* end of search region */
|
|
|
d2399a |
const char *buf; /* start of search region */
|
|
|
d2399a |
const char *end;
|
|
|
d2399a |
- size_t lines;
|
|
|
d2399a |
+ size_t lines, linecnt, bytecnt;
|
|
|
d2399a |
|
|
|
d2399a |
+ linecnt = m->str_range;
|
|
|
d2399a |
+ bytecnt = linecnt * 80;
|
|
|
d2399a |
+
|
|
|
d2399a |
+ if (bytecnt == 0) {
|
|
|
d2399a |
+ bytecnt = 8192;
|
|
|
d2399a |
+ }
|
|
|
d2399a |
+ if (bytecnt > nbytes) {
|
|
|
d2399a |
+ bytecnt = nbytes;
|
|
|
d2399a |
+ }
|
|
|
d2399a |
if (s == NULL) {
|
|
|
d2399a |
ms->search.s_len = 0;
|
|
|
d2399a |
ms->search.s = NULL;
|
|
|
d2399a |
return 0;
|
|
|
d2399a |
}
|
|
|
d2399a |
buf = RCAST(const char *, s) + offset;
|
|
|
d2399a |
- end = last = RCAST(const char *, s) + nbytes;
|
|
|
d2399a |
+ end = last = RCAST(const char *, s) + bytecnt;
|
|
|
d2399a |
/* mget() guarantees buf <= last */
|
|
|
d2399a |
for (lines = linecnt, b = buf; lines && b < end &&
|
|
|
d2399a |
((b = CAST(const char *,
|
|
|
d2399a |
@@ -1044,7 +1053,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|
|
|
d2399a |
b++;
|
|
|
d2399a |
}
|
|
|
d2399a |
if (lines)
|
|
|
d2399a |
- last = RCAST(const char *, s) + nbytes;
|
|
|
d2399a |
+ last = RCAST(const char *, s) + bytecnt;
|
|
|
d2399a |
|
|
|
d2399a |
ms->search.s = buf;
|
|
|
d2399a |
ms->search.s_len = last - buf;
|
|
|
d2399a |
@@ -1118,7 +1127,6 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
d2399a |
int *need_separator, int *returnval)
|
|
|
d2399a |
{
|
|
|
d2399a |
uint32_t soffset, offset = ms->offset;
|
|
|
d2399a |
- uint32_t count = m->str_range;
|
|
|
d2399a |
int rv, oneed_separator;
|
|
|
d2399a |
char *sbuf, *rbuf;
|
|
|
d2399a |
union VALUETYPE *p = &ms->ms_value;
|
|
|
d2399a |
@@ -1130,13 +1138,12 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
d2399a |
}
|
|
|
d2399a |
|
|
|
d2399a |
if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
|
|
|
d2399a |
- (uint32_t)nbytes, count) == -1)
|
|
|
d2399a |
+ (uint32_t)nbytes, m) == -1)
|
|
|
d2399a |
return -1;
|
|
|
d2399a |
|
|
|
d2399a |
if ((ms->flags & MAGIC_DEBUG) != 0) {
|
|
|
d2399a |
fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
|
|
|
d2399a |
- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
|
|
|
d2399a |
- nbytes, count);
|
|
|
d2399a |
+ "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
|
|
|
d2399a |
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
|
|
|
d2399a |
}
|
|
|
d2399a |
|
|
|
d2399a |
@@ -1627,7 +1634,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
|
|
d2399a |
if ((ms->flags & MAGIC_DEBUG) != 0)
|
|
|
d2399a |
fprintf(stderr, "indirect +offs=%u\n", offset);
|
|
|
d2399a |
}
|
|
|
d2399a |
- if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
|
|
|
d2399a |
+ if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
|
|
|
d2399a |
return -1;
|
|
|
d2399a |
ms->offset = offset;
|
|
|
d2399a |
|
|
|
d2399a |
@@ -2057,7 +2064,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
|
|
d2399a |
zval *retval;
|
|
|
d2399a |
zval *subpats;
|
|
|
d2399a |
char *haystack;
|
|
|
d2399a |
-
|
|
|
d2399a |
+
|
|
|
d2399a |
MAKE_STD_ZVAL(retval);
|
|
|
d2399a |
ALLOC_INIT_ZVAL(subpats);
|
|
|
d2399a |
|
|
|
d2399a |
--
|
|
|
d2399a |
1.9.2
|
|
|
d2399a |
|
|
|
d2399a |
From 61ec9b5b0f80bc6016548d48f433fe22e2dc24ec Mon Sep 17 00:00:00 2001
|
|
|
d2399a |
From: Stanislav Malyshev <stas@php.net>
|
|
|
d2399a |
Date: Mon, 4 Aug 2014 00:08:08 -0700
|
|
|
d2399a |
Subject: [PATCH] add test
|
|
|
d2399a |
|
|
|
d2399a |
---
|
|
|
d2399a |
ext/fileinfo/tests/cve-2014-3538.phpt | 35 +++++++++++++++++++++++++++++++++++
|
|
|
d2399a |
1 file changed, 35 insertions(+)
|
|
|
d2399a |
create mode 100644 ext/fileinfo/tests/cve-2014-3538.phpt
|
|
|
d2399a |
|
|
|
d2399a |
diff --git a/ext/fileinfo/tests/cve-2014-3538.phpt b/ext/fileinfo/tests/cve-2014-3538.phpt
|
|
|
d2399a |
new file mode 100644
|
|
|
d2399a |
index 0000000..d6bc9c6
|
|
|
d2399a |
--- /dev/null
|
|
|
d2399a |
+++ b/ext/fileinfo/tests/cve-2014-3538.phpt
|
|
|
d2399a |
@@ -0,0 +1,35 @@
|
|
|
d2399a |
+--TEST--
|
|
|
d2399a |
+Bug #66731: file: extensive backtraking
|
|
|
d2399a |
+--SKIPIF--
|
|
|
d2399a |
+
|
|
|
d2399a |
+if (!class_exists('finfo'))
|
|
|
d2399a |
+ die('skip no fileinfo extension');
|
|
|
d2399a |
+--FILE--
|
|
|
d2399a |
+
|
|
|
d2399a |
+$fd = __DIR__.'/cve-2014-3538.data';
|
|
|
d2399a |
+
|
|
|
d2399a |
+file_put_contents($fd,
|
|
|
d2399a |
+ 'try:' .
|
|
|
d2399a |
+ str_repeat("\n", 1000000));
|
|
|
d2399a |
+
|
|
|
d2399a |
+$fi = finfo_open(FILEINFO_NONE);
|
|
|
d2399a |
+$t = microtime(true);
|
|
|
d2399a |
+var_dump(finfo_file($fi, $fd));
|
|
|
d2399a |
+$t = microtime(true) - $t;
|
|
|
d2399a |
+finfo_close($fi);
|
|
|
d2399a |
+if ($t < 1) {
|
|
|
d2399a |
+ echo "Ok\n";
|
|
|
d2399a |
+} else {
|
|
|
d2399a |
+ printf("Failed, time=%.2f\n", $t);
|
|
|
d2399a |
+}
|
|
|
d2399a |
+
|
|
|
d2399a |
+?>
|
|
|
d2399a |
+Done
|
|
|
d2399a |
+--CLEAN--
|
|
|
d2399a |
+
|
|
|
d2399a |
+@unlink(__DIR__.'/cve-2014-3538.data');
|
|
|
d2399a |
+?>
|
|
|
d2399a |
+--EXPECTF--
|
|
|
d2399a |
+string(%d) "%s"
|
|
|
d2399a |
+Ok
|
|
|
d2399a |
+Done
|
|
|
d2399a |
\ No newline at end of file
|
|
|
d2399a |
--
|
|
|
d2399a |
1.9.2
|
|
|
d2399a |
|