Bug 698860 - Infinite Loop in pdf_parse_array function (source/pdf/pdf-parse.c)
Infinite Loop in pdf_parse_array function (source/pdf/pdf-parse.c)
Status: RESOLVED FIXED
Product: MuPDF
Classification: Unclassified
Component: mupdf
1.12
PC Linux
: P4 major
Assigned To: muPDF bugs
Bug traffic
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2018-01-13 09:34 UTC by probefuzzer
Modified: 2018-01-16 19:15 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description probefuzzer 2018-01-13 09:34:17 UTC
On 1.12.0 (the latest version):
there is an infinite loop and application hang in the pdf_parse_array function (source/pdf/pdf-parse.c), which could be triggered by the POC with command: mutool draw $POC

Looking into the pdf_parse_array function (source/pdf/pdf-parse.c), we found that the "while(1)" loop terminates only when the program encountered a PDF_TOK_CLOSE_ARRAY token. However, the tokens could be manipulated by a crafted pdf file, and an infinite loop happens when PDF_TOK_CLOSE_ARRAY does not appear. 

Recommended fix: the program should terminate when "EOF" token is encountered. Therefore, we recommend adding following statements around line 404. 
    case PDF_TOK_EOF:
        goto end;

The code segment is:
    361 pdf_parse_array(fz_context *ctx, pdf_document *doc, fz_stream *file, pdf_lexbuf *buf)
    362 {
    ...
    373         fz_try(ctx)
    374         {
    375                 while (1)
    376                 {
    377                         tok = pdf_lex(ctx, file, buf);
    ...
    402                         switch (tok)
    403                         {
    404                         case PDF_TOK_CLOSE_ARRAY:
    405                                 op = ary;
    406                                 goto end;
    ...
    462                         }
    463                 }
    464 end:
    465                 {}
    466         }
    ...
    472         return op;
    473 }

POC:
https://github.com/ProbeFuzzer/poc/blob/master/mupdf/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf

backtrace:
#0  0x00007ffff66dd9d6 in __memmove_ssse3 () from /lib64/libc.so.6
#1  0x00007ffff6e97c58 in Reallocate (stack=0x7fffffffc3b0, new_size=140733826750448, old_ptr=0x7fff25c05800)
    at ../../../../src/libsanitizer/asan/asan_allocator2.cc:485
#2  __asan::asan_realloc (p=p@entry=0x7fff25c05800, size=size@entry=2451898200, stack=stack@entry=0x7fffffffc3b0)
    at ../../../../src/libsanitizer/asan/asan_allocator2.cc:615
#3  0x00007ffff6f08408 in __interceptor_realloc (ptr=0x7fff25c05800, size=2451898200)
    at ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:83
#4  0x00000000006ae500 in do_scavenging_realloc (size=2451898200, p=0x7fff25c05800, ctx=0x60e00000df60) at source/fitz/memory.c:42
#5  fz_resize_array (ctx=ctx@entry=0x60e00000df60, p=0x7fff25c05800, count=count@entry=306487275, size=size@entry=8)
    at source/fitz/memory.c:171
#6  0x00000000008c2cee in pdf_array_grow (obj=0x60400000d790, ctx=0x60e00000df60) at source/pdf/pdf-object.c:573
#7  pdf_array_push (ctx=0x60e00000df60, obj=0x60400000d790, item=<optimized out>) at source/pdf/pdf-object.c:722
#8  0x00000000008c3734 in pdf_array_push_drop (ctx=ctx@entry=0x60e00000df60, obj=obj@entry=0x60400000d790, item=0x1a6)
    at source/pdf/pdf-object.c:734
#9  0x00000000008f2040 in pdf_parse_array (ctx=ctx@entry=0x60e00000df60, doc=doc@entry=0x631000014800, file=file@entry=0x60800000bf20, 
    buf=buf@entry=0x631000014980) at source/pdf/pdf-parse.c:460
#10 0x00000000008f1699 in pdf_parse_dict (ctx=ctx@entry=0x60e00000df60, doc=doc@entry=0x631000014800, file=file@entry=0x60800000bf20, 
    buf=buf@entry=0x631000014980) at source/pdf/pdf-parse.c:512
#11 0x00000000008f3057 in pdf_parse_ind_obj (ctx=ctx@entry=0x60e00000df60, doc=doc@entry=0x631000014800, file=<optimized out>, 
    buf=buf@entry=0x631000014980, onum=onum@entry=0x7fffffffd170, ogen=ogen@entry=0x7fffffffd1b0, ostmofs=0x61300000d6c0, 
    try_repair=0x7fffffffd1f0) at source/pdf/pdf-parse.c:650
#12 0x0000000000967db0 in pdf_cache_object (ctx=ctx@entry=0x60e00000df60, doc=doc@entry=0x631000014800, num=num@entry=6)
    at source/pdf/pdf-xref.c:1929
#13 0x000000000096e322 in pdf_resolve_indirect (ctx=0x60e00000df60, ref=<optimized out>) at source/pdf/pdf-xref.c:2025
#14 0x000000000096e455 in pdf_resolve_indirect_chain (ctx=0x60e00000df60, ref=0x60300000e920) at source/pdf/pdf-xref.c:2051
#15 0x00000000008be80d in pdf_mark_obj (ctx=ctx@entry=0x60e00000df60, obj=obj@entry=0x60300000e920) at source/pdf/pdf-object.c:1610
#16 0x00000000008dceef in pdf_resources_use_overprint (ctx=ctx@entry=0x60e00000df60, rdb=rdb@entry=0x60300000e920)
    at source/pdf/pdf-page.c:527
#17 0x00000000008e6995 in pdf_load_page (ctx=<optimized out>, doc=<optimized out>, number=<optimized out>) at source/pdf/pdf-page.c:1109
#18 0x000000000043731a in drawpage (ctx=ctx@entry=0x60e00000df60, doc=doc@entry=0x631000014800, pagenum=pagenum@entry=1)
    at source/tools/mudraw.c:1044
#19 0x0000000000439167 in drawrange (ctx=ctx@entry=0x60e00000df60, doc=<optimized out>, range=<optimized out>, 
    range@entry=0x154da20 "1-N") at source/tools/mudraw.c:1196
#20 0x000000000043d091 in mudraw_main (argc=<optimized out>, argv=<optimized out>) at source/tools/mudraw.c:1919
#21 0x0000000000423d0f in main (argc=<optimized out>, argv=<optimized out>) at source/tools/mutool.c:127
Comment 1 probefuzzer 2018-01-13 21:47:37 UTC
For this issue, CVE-2018-5686 is assigned.
Comment 2 xncd 2018-01-15 21:51:54 UTC
I could not reproduce this:

mupdf-1.12.0-source $ uname -r
4.14.13-300.fc27.x86_64

mupdf-1.12.0-source $ ldd build/release/mutool 
	linux-vdso.so.1 (0x00007ffefa991000)
	libasan.so.4 => /lib64/libasan.so.4 (0x00007fcd9b37b000)

mupdf-1.12.0-source $ ./build/release/mutool draw ~/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
error: cannot parse token in array
warning: cannot load object (6 0 R) into cache
page /home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf 1
error: cycle in page tree
error: cannot draw '/home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf'
mupdf-1.12.0-source $
Comment 3 probefuzzer 2018-01-16 19:15:06 UTC
(In reply to xncd from comment #2)

Hi xncd, thanks for your work.
This issue is reproducible in commit fd0bf575229a79bc22901b0bd8ba4dbd356faa22, the latest commit at the time we tested it. And it is fixed in the commit b70eb93f6936c03d8af52040bbca4d4a7db39079.

This issue can be closed. Thanks.
 

> I could not reproduce this:
> 
> mupdf-1.12.0-source $ uname -r
> 4.14.13-300.fc27.x86_64
> 
> mupdf-1.12.0-source $ ldd build/release/mutool 
> 	linux-vdso.so.1 (0x00007ffefa991000)
> 	libasan.so.4 => /lib64/libasan.so.4 (0x00007fcd9b37b000)
> 
> mupdf-1.12.0-source $ ./build/release/mutool draw
> ~/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> page
> /home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf 1
> error: cycle in page tree
> error: cannot draw
> '/home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf'
> mupdf-1.12.0-source $

(In reply to xncd from comment #2)
> I could not reproduce this:
> 
> mupdf-1.12.0-source $ uname -r
> 4.14.13-300.fc27.x86_64
> 
> mupdf-1.12.0-source $ ldd build/release/mutool 
> 	linux-vdso.so.1 (0x00007ffefa991000)
> 	libasan.so.4 => /lib64/libasan.so.4 (0x00007fcd9b37b000)
> 
> mupdf-1.12.0-source $ ./build/release/mutool draw
> ~/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> page
> /home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf 1
> error: cycle in page tree
> error: cannot draw
> '/home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf'
> mupdf-1.12.0-source $

(In reply to xncd from comment #2)
> I could not reproduce this:
> 
> mupdf-1.12.0-source $ uname -r
> 4.14.13-300.fc27.x86_64
> 
> mupdf-1.12.0-source $ ldd build/release/mutool 
> 	linux-vdso.so.1 (0x00007ffefa991000)
> 	libasan.so.4 => /lib64/libasan.so.4 (0x00007fcd9b37b000)
> 
> mupdf-1.12.0-source $ ./build/release/mutool draw
> ~/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.pdf
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> error: cannot parse token in array
> warning: cannot load object (6 0 R) into cache
> page
> /home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf 1
> error: cycle in page tree
> error: cannot draw
> '/home/sfowler/Downloads/mupdf_1-12-0_mutool_infinite-loop_pdf_parse_array.
> pdf'
> mupdf-1.12.0-source $