Bug 700446

Summary: SEGV in fz_load_page
Product: MuPDF Reporter: zerokeeper <0x0keeper>
Component: mupdfAssignee: MuPDF bugs <mupdf-bugs>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P4    
Version: 1.14.0   
Hardware: PC   
OS: All   
Customer: Word Size: ---
Attachments: mupdf-test.zip

Description zerokeeper 2019-01-05 14:56:57 UTC
Hi,mupdf team,i found a segv  bug  in function fz_load_page of file source/fitz/document.c

The bug is trigered by:
./mutool draw -F svg -o out.svg mupdf-test.zip

The asan debug info is as follows:


➜  sanitize ./mutool draw -F svg -o out.svg mupdf-test.zip
AddressSanitizer:DEADLYSIGNAL
=================================================================
==24330==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000004 (pc 0x0000005ce44e bp 0x7ffff2043b70 sp 0x7ffff2043b30 T0)
==24330==The signal is caused by a WRITE memory access.
==24330==Hint: address points to the zero page.
    #0 0x5ce44d in fz_load_page /root/test/mupdf-1.14.0-source/source/fitz/document.c:333:16
    #1 0x526728 in drawpage /root/test/mupdf-1.14.0-source/source/tools/mudraw.c:1039:9
    #2 0x520b49 in drawrange /root/test/mupdf-1.14.0-source/source/tools/mudraw.c:1206:6
    #3 0x51d4ac in mudraw_main /root/test/mupdf-1.14.0-source/source/tools/mudraw.c:1921:7
    #4 0x5178f7 in main /root/test/mupdf-1.14.0-source/source/tools/mutool.c:132:12
    #5 0x7f24ca53809a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
    #6 0x41e7e9 in _start (/root/test/mupdf-1.14.0-source/build/sanitize/mutool+0x41e7e9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/test/mupdf-1.14.0-source/source/fitz/document.c:333:16 in fz_load_page
==24330==ABORTING


the gdb debug info is as follow:

➜  sanitize gdb -q mutool
GEF for linux ready, type `gef' to start, `gef config' to configure
68 commands loaded for GDB 7.12.0.20161007-git using Python engine 3.6
[*] 5 commands could not be loaded, run `gef missing` to know why.
Reading symbols from mutool...done.
gef➤  r draw -F svg -o out.svg test.zip
Starting program: /root/test/mupdf-1.14.0-source/build/sanitize/mutool draw -F svg -o out.svg test.zip
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0
$rbx   : 0x0
$rcx   : 0x8b0
$rdx   : 0x00000000042680f0  →  0x0000000000000003
$rsp   : 0x00007fffffffd8b0  →  0x00007ffff7c28fa8  →  0x0000000000000000
$rbp   : 0x00007fffffffd8f0  →  0x00007fffffffddf0  →  0x00007fffffffded0  →  0x00007fffffffe1d0  →  0x00007fffffffe2f0  →  0x00000000012f4db0  →  <__libc_csu_init+0> push r15
$rsi   : 0x000060e000000120  →  0x0000000000000001
$rdi   : 0x4
$rip   : 0x00000000005ce44e  →  <fz_load_page+702> mov DWORD PTR [rdi], r15d
$r8    : 0x0
$r9    : 0x1
$r10   : 0x00000ffffffffba4  →  0x0000000000000000
$r11   : 0x00007fffffffde40  →  0x0000608000000001  →  0x1000000000cc6e96
$r12   : 0x000060e000000120  →  0x0000000000000001
$r13   : 0x00000c1c00000033  →  0x0000000000000000
$r14   : 0xfffffffffffffffc
$r15   : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
──────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffd8b0│+0x0000: 0x00007ffff7c28fa8  →  0x0000000000000000	 ← $rsp
0x00007fffffffd8b8│+0x0008: 0x000060e000000198  →  0x0000000000000000
0x00007fffffffd8c0│+0x0010: 0x000060e000000040  →  0x0000000000000000
0x00007fffffffd8c8│+0x0018: 0x00007fffffffda60  →  0x0000000000000000
0x00007fffffffd8d0│+0x0020: 0x000010007fff7b30  →  0xf2f2f8f8f1f1f1f1
0x00007fffffffd8d8│+0x0028: 0x000060e000000120  →  0x0000000000000001
0x00007fffffffd8e0│+0x0030: 0xfffffffffffffffc
0x00007fffffffd8e8│+0x0038: 0x000060e000000040  →  0x0000000000000000
────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
     0x5ce440 <fz_load_page+688> mov    al, BYTE PTR [rax+0x7fff8000]
     0x5ce446 <fz_load_page+694> test   al, al
     0x5ce448 <fz_load_page+696> jne    0x5ce680 <fz_load_page+1264>
 →   0x5ce44e <fz_load_page+702> mov    DWORD PTR [rdi], r15d
     0x5ce451 <fz_load_page+705> cmp    BYTE PTR [r13+0x7fff8000], 0x0
     0x5ce459 <fz_load_page+713> mov    rsi, QWORD PTR [rbp-0x38]
     0x5ce45d <fz_load_page+717> jne    0x5ce6fd <fz_load_page+1389>
     0x5ce463 <fz_load_page+723> lea    rdi, [rbx+0x60]
     0x5ce467 <fz_load_page+727> mov    rax, rdi
──────────────────────────────────────────────────────────────────── source:source/fitz/document.c+333 ────
    328	 			return fz_keep_page(ctx, page);
    329
    330	 	if (doc && doc->load_page)
    331	 	{
    332	 		page = doc->load_page(ctx, doc, number);
 →  333	 		page->number = number;
    334
    335	 		/* Insert new page at the head of the list of open pages. */
    336	 		if ((page->next = doc->open) != NULL)
    337	 			doc->open->prev = &page->next;
    338	 		doc->open = page;
────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "mutool", stopped, reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x5ce44e → fz_load_page(ctx=0x60e000000040, doc=0x60e000000120, number=0x0)
[#1] 0x526729 → drawpage(ctx=0x60e000000040, doc=0x60e000000120, pagenum=0x1)
[#2] 0x520b4a → drawrange(ctx=0x60e000000040, doc=0x60e000000120, range=0x130f103 <.str.22+3> "")
[#3] 0x51d4ad → mudraw_main(argc=<optimized out>, argv=0x7fffffffe3e0)
[#4] 0x5178f8 → main(argc=<optimized out>, argv=0x7fffffffe3e0)
───────────────────────────────────────────────────────────────────────────────────────────────────────────
0x00000000005ce44e in fz_load_page (ctx=0x60e000000040, doc=0x60e000000120, number=0x0) at source/fitz/document.c:333
333			page->number = number;
gef➤
Comment 1 zerokeeper 2019-01-05 14:58:37 UTC
Created attachment 16646 [details]
mupdf-test.zip
Comment 2 Tor Andersson 2019-01-07 11:00:43 UTC
I cannot reproduce.

$ mutool draw -F svg -o out.svg ~/Downloads/mupdf-test.zip 
error: cannot load page 0
error: cannot draw '/home/tor/Downloads/mupdf-test.zip'
Comment 3 Tor Andersson 2019-01-07 11:03:49 UTC
This bug was already fixed in commit faf47b94e24314d74907f3f6bc874105f2c962ed
Author: Sebastian Rasmussen <sebras@gmail.com>
Date:   Wed Sep 26 03:31:05 2018 +0800

    Throw when page number is out of range.
    
    Other code depends on this and does not handle
    a page pointer being NULL well.