Patch cve-2014-3538.patch for Filesystem function related Bug #67705
Patch version 2014-07-29 06:44 UTC
Return to Bug #67705 |
Download this patch
Patch Revisions:
Developer: remi@php.net
diff -up ./data_file.c.cve ./data_file.c
--- ./data_file.c.cve 2014-07-29 07:48:50.873006117 +0200
+++ ./data_file.c 2014-07-29 07:40:19.243602276 +0200
@@ -121057,7 +121057,7 @@ const unsigned char php_magic_database[2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x3D, 0x1B, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5E, 0x5C, 0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x5C,
0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x5B, 0x7B, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff -up ./libmagic/softmagic.c.cve ./libmagic/softmagic.c
--- ./libmagic/softmagic.c.cve 2014-07-29 07:49:11.599099224 +0200
+++ ./libmagic/softmagic.c 2014-07-29 08:28:27.170260472 +0200
@@ -67,7 +67,7 @@ private int32_t mprint(struct magic_set
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 *, int);
private int print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *);
@@ -1038,7 +1038,7 @@ mdebug(uint32_t offset, const char *str,
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
@@ -1058,15 +1058,24 @@ mcopy(struct magic_set *ms, union VALUET
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 *,
@@ -1079,7 +1088,7 @@ mcopy(struct magic_set *ms, union VALUET
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;
@@ -1150,7 +1159,6 @@ mget(struct magic_set *ms, const unsigne
int *need_separator, int *returnval)
{
uint32_t soffset, offset = ms->offset;
- uint32_t count = m->str_range;
int rv, oneed_separator, in_type;
char *sbuf, *rbuf;
union VALUETYPE *p = &ms->ms_value;
@@ -1162,13 +1170,12 @@ mget(struct magic_set *ms, const unsigne
}
if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
- (uint32_t)nbytes, count) == -1)
+ (uint32_t)nbytes, m) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
- nbytes, count);
+ "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
}
@@ -1661,7 +1668,7 @@ mget(struct magic_set *ms, const unsigne
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect +offs=%u\n", offset);
}
- 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;
@@ -2093,7 +2100,7 @@ magiccheck(struct magic_set *ms, struct
zval *retval;
zval *subpats;
char *haystack;
-
+
MAKE_STD_ZVAL(retval);
ALLOC_INIT_ZVAL(subpats);
diff -up ./tests/cve-2014-3538.phpt.cve ./tests/cve-2014-3538.phpt
--- ./tests/cve-2014-3538.phpt.cve 2014-07-29 08:24:03.654996032 +0200
+++ ./tests/cve-2014-3538.phpt 2014-07-29 08:25:58.839548904 +0200
@@ -0,0 +1,35 @@
+--TEST--
+Bug #66731: file: extensive backtraking
+--SKIPIF--
+<?php
+if (!class_exists('finfo'))
+ die('skip no fileinfo extension');
+--FILE--
+<?php
+$fd = __DIR__.'/cve-2014-3538.data';
+
+file_put_contents($fd,
+ 'try:' .
+ str_repeat("\n", 1000000));
+
+$fi = finfo_open(FILEINFO_NONE);
+$t = microtime(true);
+var_dump(finfo_file($fi, $fd));
+$t = microtime(true) - $t;
+finfo_close($fi);
+if ($t < 1) {
+ echo "Ok\n";
+} else {
+ printf("Failed, time=%.2f\n", $t);
+}
+
+?>
+Done
+--CLEAN--
+<?php
+@unlink(__DIR__.'/cve-2014-3538.data');
+?>
+--EXPECTF--
+string(%d) "%s"
+Ok
+Done
\ Pas de fin de ligne à la fin du fichier
|