Menu

#46 excessive memory allocation crash at src/doc/PdfPagesTreeCache.cpp:45 when nInitialSize=0xffffffff

SVN TRUNK
closed
nobody
security (37)
2021-08-18
2019-04-03
Tao
No

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➤
1 Attachments

Related

Tickets: #1
Tickets: #2
Tickets: #3
Tickets: #4
Tickets: #5

Discussion

  • Tao

    Tao - 2019-04-03

    Crash when using gdb debugging.

    gdb -q -arg ~/vuln-fuzz/program/podofo-r1974/afl-build/install/bin/podofocrop output/crashes/id\:000000\,sig\:06\,src\:000096\,op\:ext_UO\,pos\:181 out.pdf
    gef  r
    Starting program: /home/lt/vuln-fuzz/program/podofo-r1974/afl-build/install/bin/podofocrop output/crashes/id:000000,sig:06,src:000096,op:ext_UO,pos:181 out.pdf
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    Cropping file:  output/crashes/id:000000,sig:06,src:000096,op:ext_UO,pos:181
    Writing to   :  out.pdf
    terminate called after throwing an instance of 'std::length_error'
      what():  deque::_M_new_elements_at_front
    
    Program received signal SIGABRT, Aborted.
    0x00007ffff6624428 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:54
    54      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    [ Legend: Modified register | Code | Heap | Stack | String ]
    ─────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
    $rax   : 0x0
    $rbx   : 0x0000000000a871b8    "deque::_M_new_elements_at_front"
    $rcx   : 0x00007ffff6624428    0x2077fffff0003d48 ("H="?)
    $rdx   : 0x6
    $rsp   : 0x00007fffffffdd18    0x00007ffff662602a    <abort+362> mov rdx, QWORD PTR fs:0x10
    $rbp   : 0x0000000000a6bc60    0x00007ffff69b4540    0x00000000fbad2887
    $rsi   : 0xb6f3
    $rdi   : 0xb6f3
    $rip   : 0x00007ffff6624428    0x2077fffff0003d48 ("H="?)
    $r8    : 0x00007ffff69b5770    0x0000000000000000
    $r9    : 0x00007ffff7fdd740    0x00007ffff7fdd740    [loop detected]
    $r10   : 0x8
    $r11   : 0x206
    $r12   : 0x0000000000a8e860    0x0000000000000000
    $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 ────
    0x00007fffffffdd18+0x0000: 0x00007ffff662602a    <abort+362> mov rdx, QWORD PTR fs:0x10         $rsp
    0x00007fffffffdd20+0x0008: 0x0000000000000020
    0x00007fffffffdd28+0x0010: 0x0000000000000000
    0x00007fffffffdd30+0x0018: 0x0000000000000000
    0x00007fffffffdd38+0x0020: 0x0000000000000000
    0x00007fffffffdd40+0x0028: 0x0000000000000000
    0x00007fffffffdd48+0x0030: 0x0000000000000000
    0x00007fffffffdd50+0x0038: 0x0000000000000000
    ───────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
       0x7ffff662441e <raise+46>       mov    eax, 0xea
       0x7ffff6624423 <raise+51>       movsxd rdi, ecx
       0x7ffff6624426 <raise+54>       syscall
      0x7ffff6624428 <raise+56>       cmp    rax, 0xfffffffffffff000
       0x7ffff662442e <raise+62>       ja     0x7ffff6624450 <__GI_raise+96>
       0x7ffff6624430 <raise+64>       repz   ret
       0x7ffff6624432 <raise+66>       nop    WORD PTR [rax+rax*1+0x0]
       0x7ffff6624438 <raise+72>       test   ecx, ecx
       0x7ffff662443a <raise+74>       jg     0x7ffff662441b <__GI_raise+43>
    ───────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
    [#0] Id 1, Name: "podofocrop", stopped, reason: SIGABRT
    ─────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
    [#0] 0x7ffff6624428  __GI_raise(sig=0x6)
    [#1] 0x7ffff662602a  __GI_abort()
    [#2] 0x7ffff6f6784d  __gnu_cxx::__verbose_terminate_handler()()
    [#3] 0x7ffff6f656b6  call 0x7ffff6f5efc0 <abort@plt>
    [#4] 0x7ffff6f65701  std::terminate()()
    [#5] 0x7ffff6f65919  __cxa_throw()
    [#6] 0x7ffff6f8e26f  std::__throw_length_error(char const*)()
    [#7] 0x5e8d72  std::deque<PoDoFo::PdfPage*, std::allocator<PoDoFo::PdfPage*> >::_M_new_elements_at_front(this=0xa8e5b8, __new_elems=<optimized out>)
    [#8] 0x5fa86a  std::deque<PoDoFo::PdfPage*, std::allocator<PoDoFo::PdfPage*> >::_M_reserve_elements_at_front(__n=0xffffffffffffffff, this=0xa8e5b8)
    [#9] 0x5fa86a  std::deque<PoDoFo::PdfPage*, std::allocator<PoDoFo::PdfPage*> >::_M_fill_insert(this=0xa8e5b8, __pos=<main_arena+792>, __n=0xffffffffffffffff, __x=@0x7fffffffdf88)
    ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    gef
    

    Crash when directly running

    lt@f9b96d524ea7:~/vuln-fuzz/fuzzing-afl/podofo-2019-03-22/fuzzer2-crop$ ~/vuln-fuzz/program/podofo-r1974/afl-build/install/bin/podofocrop output/crashes/id\:000000\,sig\:06\,src\:000096\,op\:ext_UO\,pos\:181 out.pdf
    Cropping file:  output/crashes/id:000000,sig:06,src:000096,op:ext_UO,pos:181
    Writing to   :  out.pdf
    terminate called after throwing an instance of 'std::length_error'
      what():  deque::_M_new_elements_at_front
    Aborted (core dumped)
    
     

    Related

    Tickets: #1
    Tickets: #2
    Tickets: #3
    Tickets: #4
    Tickets: #5
    Tickets: #6
    Tickets: #7
    Tickets: #8
    Tickets: #9

  • Tao

    Tao - 2019-04-04

    This vulnerability discovered by Tao Lv from IIE has been assigned CVE-2019-10723.

     
  • Matthew Brincke

    Matthew Brincke - 2019-05-08
    • labels: --> security
    • summary: crash at src/doc/PdfPagesTreeCache.cpp:45 when nInitalSize=0xffffffff --> excessive memory allocation crash at src/doc/PdfPagesTreeCache.cpp:45 when nInitialSize=0xffffffff
     
  • Christopher Creutzig

    Given the offending instruction is just preallocating memory for performance, I believe this should be easy to fix, using an arbitrary limit for preallocation:

    Index: src/podofo/doc/PdfPagesTreeCache.cpp
    ===================================================================
    --- src/podofo/doc/PdfPagesTreeCache.cpp    (revision 2033)
    +++ src/podofo/doc/PdfPagesTreeCache.cpp    (working copy)
    @@ -42,7 +42,9 @@
    
     PdfPagesTreeCache::PdfPagesTreeCache( int nInitialSize )
     {
    -    m_deqPageObjs.resize( nInitialSize );
    +    if (nInitialSize > 0 && nInitialSize < (1L << 20)) {
    +        m_deqPageObjs.resize( nInitialSize );
    +    }
     }
    
     PdfPagesTreeCache::~PdfPagesTreeCache()
    
     
  • zyx

    zyx - 2021-08-18

    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]

  • zyx

    zyx - 2021-08-18
    • status: open --> closed