Hi, there is a bug at src/doc/PdfPagesTreeCache.cpp:45.
43 PdfPagesTreeCache::PdfPagesTreeCache( int nInitialSize )
44 {
45 m_deqPageObjs.resize( nInitialSize );
46 }
The poc can make nInitialSize equals to 0xffffffff, which make resize operation fails.
The debug process using gdb are shown below.
execution command ./podofocrop poc out.pdf
gef➤Continuing.
Breakpoint 3, PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache (this=0xa8e5b0, nInitialSize=0xffffffff) at /home/lt/vuln-fuzz/program/podofo-r1974/src/doc/PdfPagesTreeCache.cpp:45
45 m_deqPageObjs.resize( nInitialSize );
[ Legend: Modified register | Code | Heap | Stack | String ]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x0000000000a8e890 → 0x00007ffff69b3e38 → 0x00007ffff69b3e28 → 0x00007ffff69b3e18 → 0x00007ffff69b3e08 → 0x00007ffff69b3df8 → 0x00007ffff69b3de8 → 0x00007ffff69b3dd8
$rbx : 0x0000000000a8e5b0 → 0x000000000082baf0 → 0x00000000005e0ca0 → <PoDoFo::PdfPagesTreeCache::~PdfPagesTreeCache()+0> lea rsp, [rsp-0x98]
$rcx : 0x0000000000a8ea90 → 0x0000000000000000
$rdx : 0x0000000000a8e890 → 0x00007ffff69b3e38 → 0x00007ffff69b3e28 → 0x00007ffff69b3e18 → 0x00007ffff69b3e08 → 0x00007ffff69b3df8 → 0x00007ffff69b3de8 → 0x00007ffff69b3dd8
$rsp : 0x00007fffffffdf70 → 0x0000000000a870b0 → 0x000000000082ae20 → 0x0000000000563b70 → <PoDoFo::PdfInfo::~PdfInfo()+0> lea rsp, [rsp-0x98]
$rbp : 0x0000000000a8df18 → 0x0000000000000000
$rsi : 0x2000
$rdi : 0xc0
$rip : 0x00000000005e2c1f → <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+223> movsxd rdx, r12d
$r8 : 0x00007ffff69b3e38 → 0x00007ffff69b3e28 → 0x00007ffff69b3e18 → 0x00007ffff69b3e08 → 0x00007ffff69b3df8 → 0x00007ffff69b3de8 → 0x00007ffff69b3dd8 → 0x00007ffff69b3dc8
$r9 : 0x0
$r10 : 0x00007fffffffdf10 → 0x0000000000000200
$r11 : 0x00007ffff6783f90 → 0xfffda370fffda09f
$r12 : 0xffffffff
$r13 : 0x0000000000a870b0 → 0x000000000082ae20 → 0x0000000000563b70 → <PoDoFo::PdfInfo::~PdfInfo()+0> lea rsp, [rsp-0x98]
$r14 : 0x0000000000a8af60 → 0x000000000082f2c8 → 0x0000000000695190 → <PoDoFo::PdfParserObject::~PdfParserObject()+0> lea rsp, [rsp-0x98]
$r15 : 0x0000000000a8d6b0 → 0x000000000082f2c8 → 0x0000000000695190 → <PoDoFo::PdfParserObject::~PdfParserObject()+0> lea rsp, [rsp-0x98]
$eflags: [carry PARITY adjust zero sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdf70│+0x0000: 0x0000000000a870b0 → 0x000000000082ae20 → 0x0000000000563b70 → <PoDoFo::PdfInfo::~PdfInfo()+0> lea rsp, [rsp-0x98] ← $rsp
0x00007fffffffdf78│+0x0008: 0x0000000000a8af60 → 0x000000000082f2c8 → 0x0000000000695190 → <PoDoFo::PdfParserObject::~PdfParserObject()+0> lea rsp, [rsp-0x98]
0x00007fffffffdf80│+0x0010: 0x0000000000a8d6b0 → 0x000000000082f2c8 → 0x0000000000695190 → <PoDoFo::PdfParserObject::~PdfParserObject()+0> lea rsp, [rsp-0x98]
0x00007fffffffdf88│+0x0018: 0x00000000004446ad → <PoDoFo::PdfDictionary::GetKey(PoDoFo::PdfName+0> cmp rax, rbx
0x00007fffffffdf90│+0x0020: 0x0000000000a8b630 → 0x000000000082f2c8 → 0x0000000000695190 → <PoDoFo::PdfParserObject::~PdfParserObject()+0> lea rsp, [rsp-0x98]
0x00007fffffffdf98│+0x0028: 0x000000000047c530 → <PoDoFo::PdfObject::GetIndirectKey(PoDoFo::PdfName+0> cmp BYTE PTR [rax+0x13], 0x0
0x00007fffffffdfa0│+0x0030: 0x0000007365676150 ("Pages"?)
0x00007fffffffdfa8│+0x0038: 0x0000000000000000
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x5e2c10 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+208> add rbp, rax
0x5e2c13 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+211> call 0x433bd0 <_Znwm@plt>
0x5e2c18 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+216> lea rcx, [rax+0x200]
→ 0x5e2c1f <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+223> movsxd rdx, r12d
0x5e2c22 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+226> mov QWORD PTR [rbp+0x0], rax
0x5e2c26 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+230> test rdx, rdx
0x5e2c29 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+233> mov QWORD PTR [rbx+0x30], rbp
0x5e2c2d <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+237> mov QWORD PTR [rbx+0x20], rax
0x5e2c31 <PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(int)+241> mov QWORD PTR [rbx+0x28], rcx
────────────────────────────────────────────────────────────────────────────────────────────────────────── source:/home/lt/vuln-f[...].cpp+45 ────
40
41 namespace PoDoFo {
42
43 PdfPagesTreeCache::PdfPagesTreeCache( int nInitialSize )
44 {
// nInitialSize=-0x1
→ 45 m_deqPageObjs.resize( nInitialSize );
46 }
47
48 PdfPagesTreeCache::~PdfPagesTreeCache()
49 {
50 this->ClearCache();
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "podofocrop", stopped, reason: BREAKPOINT
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x5e2c1f → PoDoFo::PdfPagesTreeCache::PdfPagesTreeCache(this=0xa8e5b0, nInitialSize=0xffffffff)
[#1] 0x5ccd08 → PoDoFo::PdfPagesTree::PdfPagesTree(this=0xa8e5a0, pPagesRoot=<optimized out>)
[#2] 0x4dd5e4 → PoDoFo::PdfDocument::InitPagesTree(this=0x7fffffffe290)
[#3] 0x56f1b7 → PoDoFo::PdfMemDocument::InitFromParser(this=0x7fffffffe290, pParser=0xa87e50)
[#4] 0x57031a → PoDoFo::PdfMemDocument::Load(this=0x7fffffffe290, pszFilename=0x7fffffffe7a8 "output/crashes/id:000000,sig:06,src:000096,op:ext_UO,pos:181", bForUpdate=0x0)
[#5] 0x43587a → main(argc=<optimized out>, argv=0x7fffffffe538)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ p nInitialSize
$4 = 0xffffffff
gef➤
Tickets: #1
Tickets: #2
Tickets: #3
Tickets: #4
Tickets: #5
Crash when using gdb debugging.
Crash when directly running
Related
Tickets: #1
Tickets:
#2Tickets:
#3Tickets:
#4Tickets:
#5Tickets:
#6Tickets:
#7Tickets:
#8Tickets:
#9This vulnerability discovered by Tao Lv from IIE has been assigned CVE-2019-10723.
Given the offending instruction is just preallocating memory for performance, I believe this should be easy to fix, using an arbitrary limit for preallocation:
Thanks for the patch. I committed it as [r2038], though a bit better would be to limit the size and preallocate only the limited number, than nothing, but I used your version as is.
Related
Commit: [r2038]