[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] qpdf: three infinite loop in libqpdf
From:       "Agostino Sarubbo" <ago () gentoo ! org>
Date:       2017-05-23 8:06:34
Message-ID: 889256.295838521-sendEmail () localhost
[Download RAW message or body]

------MIME delimiter for sendEmail-999345.197183178
Content-Type: text/plain;
        charset="UTF-8"
Content-Transfer-Encoding: 7bit

Description:
qpdf QPDF is a command-line program that does structural, content-preserving transformations on \
PDF files.

I discovered three infinite loop. Upstream didn't provide a feedback, so they might have the \
same root cause.

# qpdf $FILE -
==8000==ERROR: AddressSanitizer: stack-overflow on address 0x7fff9cf4efd8 (pc 0x7f925abe7e23 bp \
0x7fff9cf4f050 sp 0x7fff9cf4efe0 T0)  #0 0x7f925abe7e22 in \
QPDFObjectHandle::assertInitialized() const \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1380  #1 \
0x7f925abe38aa in QPDFObjectHandle::isIndirect() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:241:5  #2 \
0x7f925abe38aa in QPDFObjectHandle::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:71  #3 \
0x7f925ad2ca5d in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8  #4 \
0x7f925ad2ca5d in QPDF_Array::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:19  #5 0x7f925abe3c24 \
in QPDFObject::ObjAccessor::releaseResolved(QPDFObject*) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObject.hh:67:6  #6 \
0x7f925abe3c24 in QPDFObjectHandle::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:80  #7 \
0x7f925ad30a6e in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8  #8 \
0x7f925ad30a6e in QPDF_Dictionary::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:23  #9 \
0x7f925abe3c24 in QPDFObject::ObjAccessor::releaseResolved(QPDFObject*) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObject.hh:67:6  #10 \
0x7f925abe3c24 in QPDFObjectHandle::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:80  #11 \
0x7f925ad30a6e in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8  #12 \
0x7f925ad30a6e in QPDF_Dictionary::releaseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:23 Reproducer:
https://github.com/asarubbo/poc/blob/master/00176-qpdf-infiniteloop1
CVE:
CVE-2017-9208

############################

# qpdf $FILE -
    #0 0x427108 in __asan::Allocator::Allocate(unsigned long, unsigned long, \
__sanitizer::BufferedStackTrace*, __asan::AllocType, bool) \
/tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:323
  #1 0x50ce78 in operator new(unsigned long) \
/tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:78
  #2 0x7fe47c18de58 in std::string::_Rep::_S_create(unsigned long, unsigned long, \
std::allocator const&) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf3e58)  #3 \
0x7fe47c18ec3a in std::string::_Rep::_M_clone(std::allocator const&, unsigned long) \
(/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4c3a)  #4 0x7fe47c18ece3 in \
std::string::reserve(unsigned long) \
(/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4ce3)  #5 0x7fe47c656405 in \
std::string::push_back(char) \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:1072:10  #6 \
0x7fe47c656405 in std::string::operator+=(char) \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:968  #7 \
0x7fe47c656405 in QPDFTokenizer::presentCharacter(char) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFTokenizer.cc:189  #8 \
0x7fe47c65d19a in QPDFTokenizer::readToken(PointerHolder, std::string const&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFTokenizer.cc:519:6  #9 \
0x7fe47c61da83 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:873:23  #10 \
0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15  #11 \
0x7fe47c6122d4 in QPDFObjectHandle::parse(PointerHolder, std::string const&, QPDFTokenizer&, \
bool&, QPDFObjectHandle::StringDecrypter*, QPDF*) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:841:12  #12 \
0x7fe47c553ec1 in QPDF::readObject(PointerHolder, std::string const&, int, int, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1017:31  #13 0x7fe47c542a0b \
in QPDF::reconstruct_xref(QPDFExc&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:393:7  #14 0x7fe47c57e826 \
in QPDF::readObjectAtOffset(bool, long long, std::string const&, int, int, int&, int&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1359:6  #15 0x7fe47c59e56d \
in QPDF::resolve(int, int) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1474:7  #16 0x7fe47c5f4854 \
in QPDF::Resolver::resolve(QPDF*, int, int) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDF.hh:520:19  #17 \
0x7fe47c5f4854 in QPDFObjectHandle::dereference() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1520  #18 \
0x7fe47c626227 in QPDFObjectHandle::isName() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:184:5  #19 \
0x7fe47c626227 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1074  #20 \
0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15  #21 \
0x7fe47c6122d4 in QPDFObjectHandle::parse(PointerHolder, std::string const&, QPDFTokenizer&, \
bool&, QPDFObjectHandle::StringDecrypter*, QPDF*) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:841:12  #22 \
0x7fe47c553ec1 in QPDF::readObject(PointerHolder, std::string const&, int, int, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1017:31  #23 0x7fe47c542a0b \
in QPDF::reconstruct_xref(QPDFExc&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:393:7  #24 0x7fe47c57e826 \
in QPDF::readObjectAtOffset(bool, long long, std::string const&, int, int, int&, int&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1359:6  #25 0x7fe47c59e56d \
in QPDF::resolve(int, int) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1474:7  #26 0x7fe47c5f4854 \
in QPDF::Resolver::resolve(QPDF*, int, int) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDF.hh:520:19  #27 \
0x7fe47c5f4854 in QPDFObjectHandle::dereference() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1520  #28 \
0x7fe47c626227 in QPDFObjectHandle::isName() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:184:5  #29 \
0x7fe47c626227 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1074  #30 \
0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, \
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15 \
Reproducer: https://github.com/asarubbo/poc/blob/master/00177-pdf-infiniteloop2
CVE:
CVE-2017-9209

############################

# qpdf $FILE -
==13070==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd0ba0efb0 (pc 0x00000042711b \
bp 0x7ffd0ba0f8a0 sp 0x7ffd0ba0efb0 T0)  #0 0x42711a in __asan::Allocator::Allocate(unsigned \
long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) \
/tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:325
  #1 0x50ce78 in operator new(unsigned long) \
/tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:78
  #2 0x7f949448ae58 in std::string::_Rep::_S_create(unsigned long, unsigned long, \
std::allocator const&) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf3e58)  #3 \
0x7f949448bc3a in std::string::_Rep::_M_clone(std::allocator const&, unsigned long) \
(/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4c3a)  #4 0x7f949448bce3 in \
std::string::reserve(unsigned long) \
(/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4ce3)  #5 0x7f9494a4451d in \
std::string::push_back(char) \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:1072:10  #6 \
0x7f9494a4451d in std::string::operator+=(char) \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:968  #7 \
0x7f9494a4451d in QPDF_Name::normalizeName(std::string const&) \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Name.cc:24  #8 0x7f9494a3ddaa \
in QPDF_Dictionary::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:35:12  #9 \
0x7f949490c23f in QPDFObjectHandle::unparseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23  #10 \
0x7f9494909e8c in QPDFObjectHandle::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11  #11 \
0x7f9494a39cb0 in QPDF_Array::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:30:20  #12 \
0x7f949490c23f in QPDFObjectHandle::unparseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23  #13 \
0x7f9494909e8c in QPDFObjectHandle::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11  #14 \
0x7f9494a3de56 in QPDF_Dictionary::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:36:27  #15 \
0x7f949490c23f in QPDFObjectHandle::unparseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23  #16 \
0x7f9494909e8c in QPDFObjectHandle::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11  #17 \
0x7f9494a39cb0 in QPDF_Array::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:30:20  #18 \
0x7f949490c23f in QPDFObjectHandle::unparseResolved() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23  #19 \
0x7f9494909e8c in QPDFObjectHandle::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11  #20 \
0x7f9494a3de56 in QPDF_Dictionary::unparse() \
/tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:36:27 \
Reproducer: https://github.com/asarubbo/poc/blob/master/00177-qpdf-infiniteloop3
CVE:
CVE-2017-9210

############################

Affected version:
6.0.0

Fixed version:
N/A

Commit fix:
N/A

Credit:
These bugs were discovered by Agostino Sarubbo of Gentoo.

Timeline:
2017-02-13: bug discovered and reported to upstream
2017-05-21: blog post about the issue
2017-05-23: CVE assigned

Note:
These bugs were found with American Fuzzy Lop.

Permalink:
https://blogs.gentoo.org/ago/2017/05/21/qpdf-three-infinite-loop-in-libqpdf/

--
Agostino Sarubbo
Gentoo Linux Developer


------MIME delimiter for sendEmail-999345.197183178--


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic