Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <889256.295838521-sendEmail@localhost>
Date: Tue, 23 May 2017 08:06:34 +0000
From: "Agostino Sarubbo" <ago@...too.org>
To: "oss-security@...ts.openwall.com" <oss-security@...ts.openwall.com>
Subject: qpdf: three infinite loop in libqpdf

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


Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.