From d2b032452241708bee68d02aa02092cfbfba951a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 23 Aug 2019 09:35:53 +0200 Subject: fix #5846 --- ChangeLog | 3 ++ src/plugins/dvi_extractor.c | 88 +++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 80a5ca1..4661050 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +Fri 23 Aug 2019 09:34:35 AM CEST + Fix invalid read for malformed DVI files (#5846). -CG + Mon 13 May 2019 07:42:19 AM CEST Consistently use AS_IF and AS_CASE in configure.ac. -CG diff --git a/src/plugins/dvi_extractor.c b/src/plugins/dvi_extractor.c index 268b48c..e3aa450 100644 --- a/src/plugins/dvi_extractor.c +++ b/src/plugins/dvi_extractor.c @@ -1,6 +1,6 @@ /* This file is part of libextractor. - Copyright (C) 2002, 2003, 2004, 2012, 2017 Vidyut Samanta and Christian Grothoff + Copyright (C) 2002, 2003, 2004, 2012, 2017, 2019 Vidyut Samanta and Christian Grothoff libextractor is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -182,6 +182,8 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) size = ec->get_size (ec->cls); if (size > 16 * 1024 * 1024) return; /* too large */ + if (klen + 15 > size) + return; /* malformed klen */ if (NULL == (data = malloc ((size_t) size))) return; /* out of memory */ memcpy (data, buf, iret); @@ -189,16 +191,16 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) while (off < size) { if (0 >= (iret = ec->read (ec->cls, &buf, 16 * 1024))) - { - free (data); - return; - } + { + free (data); + return; + } memcpy (&data[off], buf, iret); off += iret; } pos = size - 1; while ( (223 == data[pos]) && - (pos > 0) ) + (pos > 0) ) pos--; if ( (2 != data[pos]) || (pos < 40) ) @@ -225,9 +227,9 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) break; if ( (pos + 45 > size) || (pos + 45 < pos) ) - goto CLEANUP; + goto CLEANUP; if (data[pos] != 139) /* expect 'bop' */ - goto CLEANUP; + goto CLEANUP; pageCount++; opos = pos; pos = getIntAt (&data[opos + 41]); @@ -238,24 +240,24 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) } /* ok, now we believe it's a dvi... */ snprintf (pages, - sizeof (pages), - "%u", - pageCount); + sizeof (pages), + "%u", + pageCount); if (0 != ec->proc (ec->cls, - "dvi", - EXTRACTOR_METATYPE_PAGE_COUNT, - EXTRACTOR_METAFORMAT_UTF8, - "text/plain", - pages, - strlen (pages) + 1)) + "dvi", + EXTRACTOR_METATYPE_PAGE_COUNT, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + pages, + strlen (pages) + 1)) goto CLEANUP; if (0 != ec->proc (ec->cls, - "dvi", - EXTRACTOR_METATYPE_MIMETYPE, - EXTRACTOR_METAFORMAT_UTF8, - "text/plain", - "application/x-dvi", - strlen ("application/x-dvi") + 1)) + "dvi", + EXTRACTOR_METATYPE_MIMETYPE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "application/x-dvi", + strlen ("application/x-dvi") + 1)) goto CLEANUP; { char comment[klen + 1]; @@ -263,18 +265,18 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) comment[klen] = '\0'; memcpy (comment, &data[15], klen); if (0 != ec->proc (ec->cls, - "dvi", - EXTRACTOR_METATYPE_COMMENT, - EXTRACTOR_METAFORMAT_C_STRING, - "text/plain", - comment, - klen + 1)) + "dvi", + EXTRACTOR_METATYPE_COMMENT, + EXTRACTOR_METAFORMAT_C_STRING, + "text/plain", + comment, + klen + 1)) goto CLEANUP; } /* try to find PDF/ps special */ pos = opos; while ( (size >= 100) && - (pos < size - 100) ) + (pos < size - 100) ) { switch (data[pos]) { @@ -284,34 +286,34 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) break; case 239: /* zzz1 */ len = data[pos + 1]; - if (pos + 2 + len < size) - if (0 != parseZZZ ((const char *) data, pos + 2, len, ec->proc, ec->cls)) - goto CLEANUP; + if ( (pos + 2 + len < size) && + (0 != parseZZZ ((const char *) data, pos + 2, len, ec->proc, ec->cls)) ) + goto CLEANUP; pos += len + 2; break; case 240: /* zzz2 */ len = getShortAt (&data[pos + 1]); - if (pos + 3 + len < size) - if (0 != parseZZZ ((const char *) data, pos + 3, len, ec->proc, ec->cls)) - goto CLEANUP; + if ( (pos + 3 + len < size) && + (0 != parseZZZ ((const char *) data, pos + 3, len, ec->proc, ec->cls)) ) + goto CLEANUP; pos += len + 3; break; case 241: /* zzz3, who uses that? */ len = (getShortAt (&data[pos + 1])) + 65536 * data[pos + 3]; - if (pos + 4 + len < size) - if (0 != parseZZZ ((const char *) data, pos + 4, len, ec->proc, ec->cls)) - goto CLEANUP; + if ( (pos + 4 + len < size) && + (0 != parseZZZ ((const char *) data, pos + 4, len, ec->proc, ec->cls)) ) + goto CLEANUP; pos += len + 4; break; case 242: /* zzz4, hurray! */ len = getIntAt (&data[pos + 1]); - if (pos + 1 + len < size) - if (0 != parseZZZ ((const char *) data, pos + 5, len, ec->proc, ec->cls)) - goto CLEANUP; + if ( (pos + 1 + len < size) && + (0 != parseZZZ ((const char *) data, pos + 5, len, ec->proc, ec->cls)) ) + goto CLEANUP; pos += len + 5; break; default: /* unsupported opcode, abort scan */ - goto CLEANUP; + goto CLEANUP; } } CLEANUP: -- cgit v1.2.3