New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crash / stack overflow with malformed input pdf #51

Closed
hannob opened this Issue Sep 2, 2015 · 8 comments

Comments

Projects
None yet
3 participants
@hannob

hannob commented Sep 2, 2015

Passing this pdf to qpdf will cause a crash:
https://crashes.fuzzing-project.org/qpdf-crash.pdf

Looking at the stack trace this seems to be an endless recursion causing a stack overflow.

Here's (part of) the stack trace when compiling qpdf with address sanitizer (latest git code):

==10615==ERROR: AddressSanitizer: stack-overflow on address 0x7ffdede32820 (pc 0x7f5ddac0dce7 bp 0x7ffdede33e50 sp 0x7ffdede32810 T0)
    #0 0x7f5ddac0dce6 in pcre_compile2 (/lib64/libpcre.so.1+0xace6)
    #1 0x78342b in PCRE::PCRE(char const*, int) /mnt/ram/qpdf/libqpdf/PCRE.cc:144:18
    #2 0x5ece64 in QPDFTokenizer::resolveLiteral() /mnt/ram/qpdf/libqpdf/QPDFTokenizer.cc:62:10
    #3 0x5f19be in QPDFTokenizer::presentCharacter(char) /mnt/ram/qpdf/libqpdf/QPDFTokenizer.cc:432:9
    #4 0x5f5091 in QPDFTokenizer::readToken(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /mnt/ram/qpdf/libqpdf/QPDFTokenizer.cc:519:6
    #5 0x5c461b in QPDFObjectHandle::parseInternal(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:873:13
    #6 0x5c4c07 in QPDFObjectHandle::parseInternal(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:939:15
    #7 0x5bcf0c in QPDFObjectHandle::parse(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*) /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:841:12
    #8 0x53b4d0 in QPDF::readObject(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, bool) /mnt/ram/qpdf/libqpdf/QPDF.cc:1020:31
    #9 0x550b21 in QPDF::readObjectAtOffset(bool, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, int&, int&) /mnt/ram/qpdf/libqpdf/QPDF.cc:1396:27
    #10 0x565da2 in QPDF::resolve(int, int) /mnt/ram/qpdf/libqpdf/QPDF.cc:1477:7
    #11 0x5a71e7 in QPDF::Resolver::resolve(QPDF*, int, int) /mnt/ram/qpdf/include/qpdf/QPDF.hh:520:13
    #12 0x5a71e7 in QPDFObjectHandle::dereference() /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:1520
    #13 0x5a88ca in QPDFObjectHandle::isInteger() /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:145:5
    #14 0x53d465 in QPDF::readObject(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, bool) /mnt/ram/qpdf/libqpdf/QPDF.cc:1121:23
    #15 0x550b21 in QPDF::readObjectAtOffset(bool, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, int&, int&) /mnt/ram/qpdf/libqpdf/QPDF.cc:1396:27
    #16 0x565da2 in QPDF::resolve(int, int) /mnt/ram/qpdf/libqpdf/QPDF.cc:1477:7
    #17 0x5a71e7 in QPDF::Resolver::resolve(QPDF*, int, int) /mnt/ram/qpdf/include/qpdf/QPDF.hh:520:13
    #18 0x5a71e7 in QPDFObjectHandle::dereference() /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:1520
    #19 0x5a88ca in QPDFObjectHandle::isInteger() /mnt/ram/qpdf/libqpdf/QPDFObjectHandle.cc:145:5
    #20 0x53d465 in QPDF::readObject(PointerHolder<InputSource>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, bool) /mnt/ram/qpdf/libqpdf/QPDF.cc:1121:23
@jberkenbilt

This comment has been minimized.

Show comment
Hide comment
@jberkenbilt

jberkenbilt Sep 10, 2016

Contributor

Note to self: saved as qpdf/misc/bugs/51.pdf

I don't see a crash, but this looks like it may be addressed by the fixes to several other issues involving handling malformed dictionaries. See #36, #45, #64.

Contributor

jberkenbilt commented Sep 10, 2016

Note to self: saved as qpdf/misc/bugs/51.pdf

I don't see a crash, but this looks like it may be addressed by the fixes to several other issues involving handling malformed dictionaries. See #36, #45, #64.

@jberkenbilt jberkenbilt added the next label Sep 10, 2016

@hannob

This comment has been minimized.

Show comment
Hide comment
@hannob

hannob Sep 11, 2016

Hmm, surprised you don't see the crash. Still crashes for me with the latest git code.
As the crash actually happens in libpcre it may be a bug in there...

hannob commented Sep 11, 2016

Hmm, surprised you don't see the crash. Still crashes for me with the latest git code.
As the crash actually happens in libpcre it may be a bug in there...

@jberkenbilt

This comment has been minimized.

Show comment
Hide comment
@jberkenbilt

jberkenbilt Sep 13, 2016

Contributor

One of the things I hope to do in the next update is to use from c++11 if building with a c++11 compiler and using pcre as a fallback if not available. What version of pcre are you using?

Contributor

jberkenbilt commented Sep 13, 2016

One of the things I hope to do in the next update is to use from c++11 if building with a c++11 compiler and using pcre as a fallback if not available. What version of pcre are you using?

@hannob

This comment has been minimized.

Show comment
Hide comment
@hannob

hannob Sep 13, 2016

8.39, latest upstream version.

hannob commented Sep 13, 2016

8.39, latest upstream version.

@asarubbo

This comment has been minimized.

Show comment
Hide comment
@asarubbo

asarubbo Feb 13, 2017

I can reproduce this issue.

asarubbo commented Feb 13, 2017

I can reproduce this issue.

This was referenced Feb 13, 2017

@jberkenbilt

This comment has been minimized.

Show comment
Hide comment
@jberkenbilt

jberkenbilt Jul 25, 2017

Contributor

I am able to reproduce the issue. I am hoping to get to it imminently. I have found fixes for #100 and #101. Next I am going to investigate this and #99.

Contributor

jberkenbilt commented Jul 25, 2017

I am able to reproduce the issue. I am hoping to get to it imminently. I have found fixes for #100 and #101. Next I am going to investigate this and #99.

jberkenbilt added a commit to jberkenbilt/qpdf that referenced this issue Jul 26, 2017

Detect recursion loops resolving objects (fixes qpdf#51)
During parsing of an object, sometimes parts of the object have to be
resolved. An example is stream lengths. If such an object directly or
indirectly points to the object being parsed, it can cause an infinite
loop. Guard against all cases of re-entrant resolution of objects.
@jberkenbilt

This comment has been minimized.

Show comment
Hide comment
@jberkenbilt

jberkenbilt Jul 26, 2017

Contributor

This one also has an easy fix.

Contributor

jberkenbilt commented Jul 26, 2017

This one also has an easy fix.

@jberkenbilt jberkenbilt added the bug label Jul 26, 2017

jberkenbilt added a commit to jberkenbilt/qpdf that referenced this issue Jul 26, 2017

Detect recursion loops resolving objects (fixes qpdf#51)
During parsing of an object, sometimes parts of the object have to be
resolved. An example is stream lengths. If such an object directly or
indirectly points to the object being parsed, it can cause an infinite
loop. Guard against all cases of re-entrant resolution of objects.

jberkenbilt added a commit to jberkenbilt/qpdf that referenced this issue Jul 26, 2017

Detect recursion loops resolving objects (fixes qpdf#51)
During parsing of an object, sometimes parts of the object have to be
resolved. An example is stream lengths. If such an object directly or
indirectly points to the object being parsed, it can cause an infinite
loop. Guard against all cases of re-entrant resolution of objects.

jberkenbilt added a commit to jberkenbilt/qpdf that referenced this issue Jul 26, 2017

Detect recursion loops resolving objects (fixes qpdf#51)
During parsing of an object, sometimes parts of the object have to be
resolved. An example is stream lengths. If such an object directly or
indirectly points to the object being parsed, it can cause an infinite
loop. Guard against all cases of re-entrant resolution of objects.

jberkenbilt added a commit to jberkenbilt/qpdf that referenced this issue Jul 26, 2017

Detect recursion loops resolving objects (fixes qpdf#51)
During parsing of an object, sometimes parts of the object have to be
resolved. An example is stream lengths. If such an object directly or
indirectly points to the object being parsed, it can cause an infinite
loop. Guard against all cases of re-entrant resolution of objects.
@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Feb 14, 2018

This has been assigned CVE-2015-9252

ghost commented Feb 14, 2018

This has been assigned CVE-2015-9252

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment