Bug 28406 - poppler crashes under certain pdf file
Summary: poppler crashes under certain pdf file
Status: RESOLVED FIXED
Alias: None
Product: poppler
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: Other Linux (All)
: medium major
Assignee: poppler-bugs
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-06 06:44 UTC by Ilya Gorenbein
Modified: 2010-06-08 11:38 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Malicious file causes crash (426 bytes, application/octet-stream)
2010-06-06 06:44 UTC, Ilya Gorenbein
Details

Description Ilya Gorenbein 2010-06-06 06:44:19 UTC
Created attachment 36085 [details]
Malicious file causes crash

Poppler version 0.12.0 crashes under certain pdf file (will be attached). 
Crash happens at file with manualy repaired root entry number (which is a number of entries objects). The number was set to 70000000. 
Crash start at poppler/XRef.cc constructXRef() function line 788 greallocn(...).
When the system fails to allocate memory poppler exits with exit(1). Unfortunately, I must say, that this is not a "conventional" way for the library. 
On the other hand, if the code is compiled with "#define USE_EXCEPTIONS 1", exceptions mechanism takes place instead of "exit". But, I did not see any "catch" expression in the code, so I am not sure about memory leaks in the case we use this flag.
And the last point. goo/gmem.cc has grealloc_checkoverflow function, which can help in such situations. It returns NULL, instead of "exception" or "exit", but in this case the code will crash at poppler/XRef.cc constructXRef() function line 790 ( entries[i] ). In this case we can tackle the problem locally, but the big problem of "exit(1)" will still exist.

P.S. One the ways to solve the problem, is to dynamicaly parse the file objects (obj), without pre-knowledge of "how many are there".

ATTACHED FILE IS MALICIOUSE !!! BE CAREFULL !!! 

The file is password protected (mal_file). 

Please, advice what to do.

Thanks a lot,
Ilya
Comment 1 Albert Astals Cid 2010-06-06 07:24:20 UTC
Please refrain from posting files that can not be opened using free tools, if you have to compress the file use zip, bz2, 7z or something, but not rar, also if you attached a compressed file please state so, i've lost 10 minutes trying to see why opening the file failed until i realized it's a rar file
Comment 2 Albert Astals Cid 2010-06-06 07:30:33 UTC
BTW both poppler 0.12.4 and 0.13.4 correctly refuse to open the file, you should stop using poppler 0.12.0
Comment 3 Ilya Gorenbein 2010-06-06 07:46:34 UTC
I just checked the version 0.12.4. It has the similiar crash effect with the similar code flow.
Comment 4 Ilya Gorenbein 2010-06-06 08:01:33 UTC
At version 0.12.4. The flow to crash is:

poppler/XRef.cc line 810 - call to 'greallocn' with newSize = 70000128
goo/gmem.cc lines 174-179 - with exit(1)
Comment 5 Ilya Gorenbein 2010-06-06 08:22:46 UTC
version 0.12.4 does not solves the problem.
Comment 6 Albert Astals Cid 2010-06-06 09:19:52 UTC
gdb -arg ~/devel/poppler-0.12/build-new/qt4/tests/test-poppler-qt4 bug-poppler28406.pdf 
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tsdgeos/devel/poppler-0.12/build-new/qt4/tests/test-poppler-qt4...done.
(gdb) r
Starting program: /home/tsdgeos/devel/poppler-0.12/build-new/qt4/tests/test-poppler-qt4 bug-poppler28406.pdf
[Thread debugging using libthread_db enabled]
Error: PDF file is damaged - attempting to reconstruct xref table...
Error: Invalid 'obj' parameters.
Error: Couldn't read xref table
doc not loaded 

Program exited with code 01.

Does not crash for me
Comment 7 Ilya Gorenbein 2010-06-06 23:44:31 UTC
This is the code I run using poppler v. 0.12.4:

The input is the filename.

//--------------------------------------------------------

#include <iostream>
#include <string>
#include <fstream>
#include <poppler/PDFDoc.h>


int main( int argc, char* argv[] )
{
    if( argc != 2 )
    {
        std::cout << "Usage: app filename" << std::endl;
        return 1;
    }// if



    // This is done to approximate a memory of the system when there is no space 
    // to allocate another big chunk of the memory. 
    // You can play with this number to reach the wanted flow.
    char* p = (char*)gmalloc( 1024*1024*1024 );// 1 Gb

    if( !p )
    {
        std::cout << "allocation failed" << std::endl;
    }// if




     GooString* fileName = new GooString( argv[1] );               
     PDFDoc m_pdf_doc_obj( fileName );

     std::cout << "end" << std::endl;

     return 0;
}// main


//--------------------------------------------------------


This is the output I've got:

Error: PDF file is damaged - attempting to reconstruct xref table...
Out of memory

//--------------------------------------------------------
Comment 8 Albert Astals Cid 2010-06-07 05:40:33 UTC
Your compilator is still dumb, line 805 has

if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) {
  error(-1, "Invalid 'obj' parameters.");
  return gFalse;
}

which means

if (70000128 >= 2147483647 / 32) {
  error(-1, "Invalid 'obj' parameters.");
  return gFalse;
}

which means

if (70000128 >= 67108864) {
  error(-1, "Invalid 'obj' parameters.");
  return gFalse;
}

That is true, you should worry why that is failing.
Comment 9 Ilya Gorenbein 2010-06-07 23:32:56 UTC
I would not start the debates about the gcc version 4.2.3. I just like to show you the problematic flow of the code.

According to your results we have:

if (70000128 >= 67108864) {
  error(-1, "Invalid 'obj' parameters.");
  return gFalse;
}

So, if newSize is less than 67108864 we continue to the:

entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry));

Number 70000000 was readen from the file. You can manually update it to 60000000. In this case newSize = 60000256 and sizeof(XRefEntry) = 32.
Which leads to allocation of 60000256 * 32 = 1920008192 bytes of memory ~1.8Gb. This or less amount of memory is not neccessary available. So, we will have an "Out of memory" message with possible exit(1) (if checkoverflow=false).
Comment 10 Albert Astals Cid 2010-06-08 11:38:05 UTC
Will be fixed in poppler 0.14.0

Next time i'll appreciate if you use the same pdf you send me, my wizard powers are quite weak lately to see you're using a different file


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.