buffer overflow in tifftops, pipeRun, Splash.cc:439
Hi, there.
There is a heap overflow in Splash.cc:439, which causes a segmentation fault and may lead to denial of service in version 22.10.0. with commit id, bc4a0d9a. It may related to a incomplete fix of issue #1022 (closed).
To reproduce, run
pdftops POC
Here is the call stack reported by ASAN:
==1424973==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x631000039b22 at pc 0x7f8081d2dc81 bp 0x7ffe4eedcb10 sp 0x7ffe4eedcb08
READ of size 1 at 0x631000039b22 thread T0
#0 0x7f8081d2dc80 in Splash::pipeRun(SplashPipe*) /benchmark/poppler/splash/Splash.cc:439:24
#1 0x7f8081d5d6c8 in Splash::drawPixel(SplashPipe*, int, int, bool) /benchmark/poppler/splash/Splash.cc:1290:9
#2 0x7f8081d5d6c8 in Splash::arbitraryTransformImage(bool (*)(void*, unsigned char*, unsigned char*), void (*)(void*, SplashBitmap*), void*, SplashColorMode, int, bool, int, int, double*, bool, bool) /benchmark/poppler/splash/Splash.cc:3924:21
#3 0x7f8081d58b0d in Splash::drawImage(bool (*)(void*, unsigned char*, unsigned char*), void (*)(void*, SplashBitmap*), void*, SplashColorMode, bool, int, int, double*, bool, bool) /benchmark/poppler/splash/Splash.cc:3622:16
#4 0x7f8081d0cb58 in SplashOutputDev::drawImage(GfxState*, Object*, Stream*, int, int, GfxImageColorMap*, bool, int const*, bool) /benchmark/poppler/poppler/SplashOutputDev.cc:3402:13
#5 0x7f80819c7387 in Gfx::doImage(Object*, Stream*, bool) /benchmark/poppler/poppler/Gfx.cc:4589:22
#6 0x7f808197d04e in Gfx::opXObject(Object*, int) /benchmark/poppler/poppler/Gfx.cc:4118:13
#7 0x7f80819a3924 in Gfx::go(bool) /benchmark/poppler/poppler/Gfx.cc:684:13
#8 0x7f80819a2a5d in Gfx::display(Object*, bool) /benchmark/poppler/poppler/Gfx.cc:645:5
#9 0x7f80819a9504 in Gfx::drawForm(Object*, Dict*, double const*, double const*, bool, bool, GfxColorSpace*, bool, bool, bool, Function*, GfxColor*) /benchmark/poppler/poppler/Gfx.cc:4835:5
#10 0x7f80819a7f65 in Gfx::doSoftMask(Object*, bool, GfxColorSpace*, bool, bool, Function*, GfxColor*) /benchmark/poppler/poppler/Gfx.cc:1288:5
#11 0x7f808199101c in Gfx::opSetExtGState(Object*, int) /benchmark/poppler/poppler/Gfx.cc:1160:21
#12 0x7f80819a3924 in Gfx::go(bool) /benchmark/poppler/poppler/Gfx.cc:684:13
#13 0x7f80819a2a5d in Gfx::display(Object*, bool) /benchmark/poppler/poppler/Gfx.cc:645:5
#14 0x7f8081b147a5 in Page::displaySlice(OutputDev*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) /benchmark/poppler/poppler/Page.cc:575:14
#15 0x7f8081c2ff00 in PSOutputDev::checkPageSlice(Page*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*) /benchmark/poppler/poppler/PSOutputDev.cc:3272:15
#16 0x7f8081b14578 in Page::displaySlice(OutputDev*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) /benchmark/poppler/poppler/Page.cc:561:15
#17 0x7f8081b1440e in Page::display(OutputDev*, double, double, int, bool, bool, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) /benchmark/poppler/poppler/Page.cc:521:5
#18 0x7f8081b2943f in PDFDoc::displayPage(OutputDev*, int, double, double, int, bool, bool, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) /benchmark/poppler/poppler/PDFDoc.cc:606:24
#19 0x4ff9c1 in main /benchmark/poppler/utils/pdftops.cc:494:18
#20 0x7f8080fa9082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
#21 0x41d54d in _start (/benchmark/poppler/build-new/utils/pdftops+0x41d54d)
0x631000039b22 is located 1554 bytes to the right of 68880-byte region [0x631000028800,0x631000039510)
allocated by thread T0 here:
#0 0x4c266f in malloc /dependence/llvm11/llvm-11.0.0.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7f8081d85135 in gmalloc(unsigned long, bool) /benchmark/poppler/goo/gmem.h:44:19
#2 0x7f8081d85135 in gmallocn(int, int, bool) /benchmark/poppler/goo/gmem.h:121:12
#3 0x7f8081d85135 in gmallocn_checkoverflow(int, int) /benchmark/poppler/goo/gmem.h:126:12
#4 0x7f8081d85135 in SplashBitmap::SplashBitmap(int, int, int, SplashColorMode, bool, bool, std::vector<GfxSeparationColorSpace*, std::allocator<GfxSeparationColorSpace*> > const*) /benchmark/poppler/splash/SplashBitmap.cc:110:28
#5 0x7f8081d16697 in SplashOutputDev::beginTransparencyGroup(GfxState*, double const*, GfxColorSpace*, bool, bool, bool) /benchmark/poppler/poppler/SplashOutputDev.cc:3987:18
#6 0x7f80819a92ec in Gfx::drawForm(Object*, Dict*, double const*, double const*, bool, bool, GfxColorSpace*, bool, bool, bool, Function*, GfxColor*) /benchmark/poppler/poppler/Gfx.cc:4822:14
SUMMARY: AddressSanitizer: heap-buffer-overflow /benchmark/poppler/splash/Splash.cc:439:24 in Splash::pipeRun(SplashPipe*)
Shadow bytes around the buggy address:
0x0c627ffff310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c627ffff360: fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff3a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff3b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==1424973==ABORTING
Aborted