Bug 1081308 (CVE-2018-7175)

Summary: VUL-1: CVE-2018-7175: xpdf: A NULL pointer dereference in readCodestream allows an attacker to cause denial of service via a JPX image with zero components.
Product: [Novell Products] SUSE Security Incidents Reporter: Karol Babioch <karol>
Component: IncidentsAssignee: Peter Simons <peter.simons>
Status: RESOLVED FIXED QA Contact: Security Team bot <security-team>
Severity: Normal    
Priority: P3 - Medium CC: pgajdos, rfrohl, smash_bz
Version: unspecified   
Target Milestone: ---   
Hardware: Other   
OS: Other   
URL: https://smash.suse.de/issue/200311/
Whiteboard: CVSSv3:SUSE:CVE-2018-7175:5.5:(AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H) CVSSv2:NVD:CVE-2018-7175:4.3:(AV:N/AC:M/Au:N/C:N/I:N/A:P) CVSSv3:NVD:CVE-2018-7175:5.5:(AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H) maint:planned:update
Found By: Security Response Team Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Bug Depends on:    
Bug Blocks: 1133493    

Description Karol Babioch 2018-02-16 09:01:46 UTC
CVE-2018-7175

An issue was discovered in xpdf 4.00. A NULL pointer dereference in
readCodestream allows an attacker to cause denial of service via a JPX image
with zero components.

References:
https://bugzilla.redhat.com/show_bug.cgi?id=1546052
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-7175
http://www.cvedetails.com/cve/CVE-2018-7175/
https://forum.xpdfreader.com/viewtopic.php?f=3&t=613
https://forum.xpdfreader.com/viewtopic.php?f=3&amp;t=613
Comment 1 Peter Simons 2018-06-21 09:22:15 UTC
We have no applicable patch for the 0 page PDF issue. Upstream has apparently fixed it in their own source code, but they did not make the change available.
Comment 2 Petr Gajdos 2023-06-12 10:05:46 UTC
Testcase:

https://github.com/skysider/FuzzVuln/blob/master/xpdf_pdftohtml_null_pointer_dereference_JPXStream_readCodestream.pdf

There's a segfault for 12/poppler with different backtrace:

(gdb) bt
#0  XRef::getNumEntry (this=0x0, offset=6803) at XRef.cc:1303
#1  0x00007ffff79483ee in Lexer::getObj (this=0x457810, obj=obj@entry=0x4575b8, cmdA=cmdA@entry=0x7ffff79d7e08 "endstream", objNum=objNum@entry=0) at Lexer.cc:594
#2  0x00007ffff795299d in Parser::shift (this=this@entry=0x457590, cmdA=cmdA@entry=0x7ffff79d7e08 "endstream", objNum=objNum@entry=0) at Parser.cc:323
#3  0x00007ffff7952b7e in Parser::makeStream (this=this@entry=0x457590, dict=dict@entry=0x7fffffffe4c0, fileKey=fileKey@entry=0x0, encAlgorithm=encAlgorithm@entry=cryptRC4, 
    keyLength=keyLength@entry=0, objNum=objNum@entry=0, objGen=objGen@entry=0, recursion=recursion@entry=1, strict=strict@entry=false) at Parser.cc:245
#4  0x00007ffff7953258 in Parser::getObj (this=this@entry=0x457590, obj=obj@entry=0x7fffffffe4c0, simpleOnly=simpleOnly@entry=false, fileKey=fileKey@entry=0x0, 
    encAlgorithm=encAlgorithm@entry=cryptRC4, keyLength=keyLength@entry=0, objNum=objNum@entry=0, objGen=objGen@entry=0, recursion=recursion@entry=0, strict=strict@entry=false)
    at Parser.cc:131
#5  0x00007ffff7965b8c in XRef::readXRef (this=this@entry=0x457220, pos=pos@entry=0x4572b8, followedXRefStm=followedXRefStm@entry=0x7fffffffe520, 
    xrefStreamObjsNum=xrefStreamObjsNum@entry=0x0) at XRef.cc:551
#6  0x00007ffff7965da9 in XRef::XRef (this=0x457220, strA=0x457050, pos=<optimized out>, mainXRefEntriesOffsetA=0, wasReconstructed=0x7fffffffe59f, reconstruct=<optimized out>)
    at XRef.cc:342
#7  0x00007ffff7956ecf in PDFDoc::setup (this=this@entry=0x456f80, ownerPassword=ownerPassword@entry=0x0, userPassword=userPassword@entry=0x0) at PDFDoc.cc:262
#8  0x00007ffff79570f8 in PDFDoc::PDFDoc (this=0x456f80, fileNameA=<optimized out>, ownerPassword=0x0, userPassword=0x0, guiDataA=<optimized out>) at PDFDoc.cc:167
#9  0x00007ffff794ba35 in LocalPDFDocBuilder::buildPDFDoc (this=<optimized out>, uri=..., ownerPassword=0x0, userPassword=0x0, guiDataA=0x0) at LocalPDFDocBuilder.cc:31
#10 0x0000000000406c06 in main (argc=2, argv=0x7fffffffe838) at pdftohtml.cc:242
(gdb) 

[probably different issue]
Comment 3 Petr Gajdos 2023-06-16 05:51:12 UTC
Segfault fixed in sr#301260.
If I should supplement the submission somehow, let me know.
Comment 5 Robert Frohl 2023-07-25 13:18:04 UTC
seeing with patched and unpatched* 0.24.4

> Syntax Error (194): Illegal character <1f> in hex string
> [..]
> AddressSanitizer:DEADLYSIGNAL
> =================================================================
> ==3839==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000001c (pc 0x7f58c51360c1 bp 0x610000000140 sp 0x7fff8ddcf010 T0)
> ==3839==The signal is caused by a READ memory access.
> ==3839==Hint: address points to the zero page.
>     #0 0x7f58c51360c1 in XRef::getNumEntry(long long) /root/src/poppler/poppler/XRef.cc:1303
>     #1 0x7f58c50e0ddf in Lexer::getObj(Object*, char const*, int) /root/src/poppler/poppler/Lexer.cc:594
>     #2 0x7f58c50fcfb1 in Parser::makeStream(Object*, unsigned char*, CryptAlgorithm, int, int, int, int, bool) /root/src/poppler/poppler/Parser.cc:245
>     #3 0x7f58c50fe043 in Parser::getObj(Object*, bool, unsigned char*, CryptAlgorithm, int, int, int, int, bool) /root/src/poppler/poppler/Parser.cc:131
>     #4 0x7f58c51322c9 in XRef::readXRef(long long*, std::vector<long long, std::allocator<long long> >*, std::vector<int, std::allocator<int> >*) /root/src/poppler/poppler/XRef.cc:551
>     #5 0x7f58c513285e in XRef::XRef(BaseStream*, long long, long long, bool*, bool) /root/src/poppler/poppler/XRef.cc:342
>     #6 0x7f58c5109f35 in PDFDoc::setup(GooString*, GooString*) /root/src/poppler/poppler/PDFDoc.cc:262
>     #7 0x7f58c510a601 in PDFDoc::PDFDoc(GooString*, GooString*, GooString*, void*) /root/src/poppler/poppler/PDFDoc.cc:167
>     #8 0x7f58c50eaac3 in LocalPDFDocBuilder::buildPDFDoc(GooString const&, GooString*, GooString*, void*) /root/src/poppler/poppler/LocalPDFDocBuilder.cc:31
>     #9 0x40a479 in main /root/src/poppler/utils/pdftohtml.cc:242
>     #10 0x7f58c47ff24c in __libc_start_main (/lib64/libc.so.6+0x3524c)
>     #11 0x40b829 in _start ../sysdeps/x86_64/start.S:120
> 
> AddressSanitizer can not provide additional info.
> SUMMARY: AddressSanitizer: SEGV /root/src/poppler/poppler/XRef.cc:1303 in XRef::getNumEntry(long long)
==3839==ABORTING

So I would say this one is still valid.
Comment 7 Petr Gajdos 2023-07-27 14:09:37 UTC
poppler-null-XRef.patch 

BEFORE

$ valgrind  -q pdftohtml xpdf_pdftohtml_null_pointer_dereference_JPXStream_readCodestream.pdf
Syntax Error (194): Illegal character <1f> in hex string
Syntax Error (202): Illegal character <59> in hex string
Syntax Error (221): Illegal character <21> in hex string
Syntax Error (243): Illegal character <50> in hex string
Syntax Error (345): Dictionary key must be a name object
Syntax Error (347): Dictionary key must be a name object
Syntax Error (351): Dictionary key must be a name object
Syntax Error (353): Dictionary key must be a name object
Syntax Error (361): Dictionary key must be a name object
==29411== Invalid read of size 4
==29411==    at 0x4F9BFBB: XRef::getNumEntry(long long) (XRef.cc:1303)
==29411==    by 0x4F7D3ED: Lexer::getObj(Object*, char const*, int) (Lexer.cc:594)
==29411==    by 0x4F87B7D: Parser::makeStream(Object*, unsigned char*, CryptAlgorithm, int, int, int, int, bool) (Parser.cc:245)
==29411==    by 0x4F88257: Parser::getObj(Object*, bool, unsigned char*, CryptAlgorithm, int, int, int, int, bool) (Parser.cc:131)
==29411==    by 0x4F9AB8B: XRef::readXRef(long long*, std::vector<long long, std::allocator<long long> >*, std::vector<int, std::allocator<int> >*) (XRef.cc:551)
==29411==    by 0x4F9ADA8: XRef::XRef(BaseStream*, long long, long long, bool*, bool) (XRef.cc:342)
==29411==    by 0x4F8BECE: PDFDoc::setup(GooString*, GooString*) (PDFDoc.cc:262)
==29411==    by 0x4F8C0F7: PDFDoc::PDFDoc(GooString*, GooString*, GooString*, void*) (PDFDoc.cc:167)
==29411==    by 0x4F80A34: LocalPDFDocBuilder::buildPDFDoc(GooString const&, GooString*, GooString*, void*) (LocalPDFDocBuilder.cc:31)
==29411==    by 0x406C05: main (pdftohtml.cc:242)
==29411==  Address 0x1c is not stack'd, malloc'd or (recently) free'd
==29411== 
==29411== 
==29411== Process terminating with default action of signal 11 (SIGSEGV)
==29411==  Access not within mapped region at address 0x1C
==29411==    at 0x4F9BFBB: XRef::getNumEntry(long long) (XRef.cc:1303)
==29411==    by 0x4F7D3ED: Lexer::getObj(Object*, char const*, int) (Lexer.cc:594)
==29411==    by 0x4F87B7D: Parser::makeStream(Object*, unsigned char*, CryptAlgorithm, int, int, int, int, bool) (Parser.cc:245)
==29411==    by 0x4F88257: Parser::getObj(Object*, bool, unsigned char*, CryptAlgorithm, int, int, int, int, bool) (Parser.cc:131)
==29411==    by 0x4F9AB8B: XRef::readXRef(long long*, std::vector<long long, std::allocator<long long> >*, std::vector<int, std::allocator<int> >*) (XRef.cc:551)
==29411==    by 0x4F9ADA8: XRef::XRef(BaseStream*, long long, long long, bool*, bool) (XRef.cc:342)
==29411==    by 0x4F8BECE: PDFDoc::setup(GooString*, GooString*) (PDFDoc.cc:262)
==29411==    by 0x4F8C0F7: PDFDoc::PDFDoc(GooString*, GooString*, GooString*, void*) (PDFDoc.cc:167)
==29411==    by 0x4F80A34: LocalPDFDocBuilder::buildPDFDoc(GooString const&, GooString*, GooString*, void*) (LocalPDFDocBuilder.cc:31)
==29411==    by 0x406C05: main (pdftohtml.cc:242)
==29411==  If you believe this happened as a result of a stack
==29411==  overflow in your program's main thread (unlikely but
==29411==  possible), you can try to increase the size of the
==29411==  main thread stack using the --main-stacksize= flag.
==29411==  The main thread stack size used in this run was 8388608.
/root/bin/vgq: line 25: 29411 Segmentation fault      (core dumped) valgrind -q $@
$

AFTER

$ valgrind  -q pdftohtml xpdf_pdftohtml_null_pointer_dereference_JPXStream_readCodestream.pdf
Syntax Error (194): Illegal character <1f> in hex string
Syntax Error (202): Illegal character <59> in hex string
Syntax Error (221): Illegal character <21> in hex string
Syntax Error (243): Illegal character <50> in hex string
Syntax Error (345): Dictionary key must be a name object
Syntax Error (347): Dictionary key must be a name object
Syntax Error (351): Dictionary key must be a name object
Syntax Error (353): Dictionary key must be a name object
Syntax Error (361): Dictionary key must be a name object
Syntax Error (6803): Missing 'endstream' or incorrect stream length
Syntax Error (488): JPX stream is missing the image header box
Syntax Error (488): JPX stream has no supported color spec
Syntax Error (905): Unknown marker segment d9 in JPX stream
Syntax Error (11492): Error in JPX codestream
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
$
Comment 8 Petr Gajdos 2023-07-27 14:12:36 UTC
Do you have a version with following changelog entry:

-------------------------------------------------------------------
Thu Jun 15 11:57:14 UTC 2023 - pgajdos@suse.com

- fix crash when XRef not available
- added patches
  fix https://gitlab.freedesktop.org/poppler/poppler/-/commit/310fbeec692b02d555e3e8dd6c851be11b25e26a
  + poppler-null-XRef.patch

If yes: could you please provide the way you use to build poppler with ASAN, so I do the same for reproducing the issue.
Comment 9 Robert Frohl 2023-09-14 13:31:41 UTC
I only tested the git state, I did not apply our patches:

> git clone && git checkout poppler-0.24.4
> cmake -Wno-dev  -DCMAKE_CXX_FLAGS="-fsanitize=address -g" -DCMAKE_C_FLAGS="-fsanitize=address -g" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -lasan" -DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=address -lasan"  -DBUILD_GTK_TESTS=OFF -DENABLE_ZLIB=ON
> make
Comment 12 Robert Frohl 2023-09-14 13:51:21 UTC
severity does not qualify this issue for the remaining affected product, closing