]> granicus.if.org Git - php/commitdiff
catch up with the previous cve-2014-3538 patch
authorAnatol Belski <ab@php.net>
Sun, 8 Mar 2015 12:09:58 +0000 (13:09 +0100)
committerAnatol Belski <ab@php.net>
Sun, 8 Mar 2015 18:47:33 +0000 (19:47 +0100)
ext/fileinfo/libmagic/softmagic.c

index ef819c2e36c2e5c03b5749b21ebbae81c3baf1fe..9ac177c0e93d33ba8e4a5ddb0dada83062e0731c 100644 (file)
@@ -1081,7 +1081,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
                        const char *last;       /* end of search region */
                        const char *buf;        /* start of search region */
                        const char *end;
-                       size_t lines, linecnt, bytecnt;
+                       size_t lines, linecnt, bytecnt, bytecnt_max;
 
                        if (s == NULL) {
                                ms->search.s_len = 0;
@@ -1097,8 +1097,15 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
                                bytecnt = m->str_range;
                        }
 
-                       if (bytecnt == 0 || bytecnt > nbytes - offset)
-                               bytecnt = nbytes - offset;
+                       /* XXX bytecnt_max is to be kept for PHP, see cve-2014-3538.
+                               PCRE might stuck if the input buffer is too big. To ensure
+                               the correctness, the check for bytecnt > nbytes is also
+                               kept (might be abundant). */
+                       bytecnt_max = nbytes - offset;
+                       bytecnt_max = bytecnt_max > (1 << 14) ? (1 << 14) : bytecnt_max;
+                       bytecnt_max = bytecnt > nbytes ? nbytes : bytecnt_max;
+                       if (bytecnt == 0 || bytecnt > bytecnt_max)
+                               bytecnt = bytecnt_max;
 
                        buf = RCAST(const char *, s) + offset;
                        end = last = RCAST(const char *, s) + bytecnt;