]> granicus.if.org Git - php/commitdiff
MFH: Fix buffer overread in libmagic and sync a skipped change from 4.26
authorScott MacVicar <scottmac@php.net>
Thu, 6 Nov 2008 03:00:04 +0000 (03:00 +0000)
committerScott MacVicar <scottmac@php.net>
Thu, 6 Nov 2008 03:00:04 +0000 (03:00 +0000)
ext/fileinfo/libmagic/funcs.c
ext/fileinfo/libmagic/softmagic.c

index 67bd0d5b0ea01377d56752780b838bfec3e7b3d0..47ce20c34436dede55856a50ef22f4afde1a669d 100644 (file)
@@ -151,6 +151,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
 {
        int m;
        int mime = ms->flags & MAGIC_MIME;
+       const unsigned char *ubuf = buf;
 
        if (nb == 0) {
                if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
@@ -182,15 +183,15 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
 #if PHP_FILEINFO_UNCOMPRESS
        /* try compression stuff */
        if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
-           (m = file_zmagic(ms, stream, inname, buf, nb)) == 0) 
+           (m = file_zmagic(ms, stream, inname, ubuf, nb)) == 0) 
 #endif
        {
                /* Check if we have a tar file */
-               if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 || (m = file_is_tar(ms, buf, nb)) == 0) {
+               if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 || (m = file_is_tar(ms, ubuf, nb)) == 0) {
                        /* try tests in /etc/magic (or surrogate magic file) */
-                       if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 || (m = file_softmagic(ms, buf, nb, BINTEST)) == 0) {
+                       if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 || (m = file_softmagic(ms, ubuf, nb, BINTEST)) == 0) {
                                /* try known keywords, check whether it is ASCII */
-                               if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 || (m = file_ascmagic(ms, buf, nb)) == 0) {
+                               if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 || (m = file_ascmagic(ms, ubuf, nb)) == 0) {
                                        /* abandon hope, all ye who remain here */
                                        if ((!mime || (mime & MAGIC_MIME_TYPE)) && file_printf(ms, mime ? "application/octet-stream" : "data") == -1) {
                                                return -1;
@@ -211,7 +212,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
                 * information from the ELF headers that cannot easily
                 * be extracted with rules in the magic file.
                 */
-               (void)file_tryelf(ms, stream, buf, nb);
+               (void)file_tryelf(ms, stream, ubuf, nb);
        }
 #endif
        return m;
index 505b2d112876d68b373ad1b57613c4240bde1b18..0eec05c8d2c5b44831dbfffe7a3d06424476dcc1 100644 (file)
@@ -185,8 +185,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                if (file_check_mem(ms, ++cont_level) == -1)
                        return -1;
 
-               while (magic[magindex+1].cont_level != 0 &&
-                   ++magindex < nmagic) {
+               while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) {
+                       magindex++;
                        m = &magic[magindex];
                        ms->line = m->lineno; /* for messages */
 
@@ -783,6 +783,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
                        const char *c;
                        const char *last;       /* end of search region */
                        const char *buf;        /* start of search region */
+                       const char *end;
                        size_t lines;
 
                        if (s == NULL) {
@@ -791,10 +792,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
                                return 0;
                        }
                        buf = (const char *)s + offset;
-                       last = (const char *)s + nbytes;
+                       end = last = (const char *)s + nbytes;
                        /* mget() guarantees buf <= last */
                        for (lines = linecnt, b = buf;
-                            lines && ((b = strchr(c = b, '\n')) || (b = strchr(c, '\r')));
+                            lines && ((b = memchr(c = b, '\n', end - b)) || (b = memchr(c, '\r', end - c)));
                             lines--, b++) {
                                last = b;
                                if (b[0] == '\r' && b[1] == '\n')