Created attachment 130054 [details] onepager.pdf When converting the PDFs that contain just a single image (large grayscale image, seems like a scan), pdftocairo segfaults. Tested on Ubuntu 14.04 x64, cairo 1.14.8 poppler 0.49.0 $ /usr/bin/pdftocairo -ps -level3 onepager.pdf out.ps Segmentation fault Yes, the file contains large image inside: PNG image data, 19833 x 28067, 8-bit/color RGBA, non-interlaced, but pdftops converts the file instantly. Here is the output from gdb: (gdb) file /usr/bin/pdftocairo Reading symbols from /usr/bin/pdftocairo...Reading symbols from /usr/lib/debug/.build-id/06/b55d5ad8a0410ac56bafe79e17dca8d917b612.debug...done. Unable to determine compiler version. done. (gdb) set args -ps -level3 onepager.pdf out.ps (gdb) run Starting program: /usr/bin/pdftocairo -ps -level3 onepager.pdf out.ps [Thread debugging using libthread_db enabled] Program received signal SIGSEGV, Segmentation fault. 0x00007ffff6575034 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) bt #0 0x00007ffff6575034 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff736b594 in _cairo_image_surface_snapshot (abstract_surface=0x5555557b9a40) at /tmp/build-debs.brV892/build/src/cairo-image-surface.c:792 #2 0x00007ffff73c0516 in _cairo_surface_snapshot_copy_on_write (surface=0x5555557ba390) at /tmp/build-debs.brV892/build/src/cairo-surface-snapshot.c:189 #3 0x00007ffff73b62ef in _cairo_surface_detach_snapshot (snapshot=0x5555557ba390) at /tmp/build-debs.brV892/build/src/cairo-surface.c:348 #4 0x00007ffff73b625d in _cairo_surface_detach_snapshots (surface=0x5555557b9a40) at /tmp/build-debs.brV892/build/src/cairo-surface.c:333 #5 0x00007ffff73b7d29 in _cairo_surface_flush (surface=0x5555557b9a40, flags=0) at /tmp/build-debs.brV892/build/src/cairo-surface.c:1545 #6 0x00007ffff73b7481 in _cairo_surface_finish_snapshots (surface=0x5555557b9a40) at /tmp/build-debs.brV892/build/src/cairo-surface.c:1017 #7 0x00007ffff73b72f1 in INT_cairo_surface_destroy (surface=0x5555557b9a40) at /tmp/build-debs.brV892/build/src/cairo-surface.c:961 #8 0x00007ffff738f51c in _cairo_pattern_fini (pattern=0x5555557b98a0) at /tmp/build-debs.brV892/build/src/cairo-pattern.c:443 #9 0x00007ffff738feea in INT_cairo_pattern_destroy (pattern=0x5555557b98a0) at /tmp/build-debs.brV892/build/src/cairo-pattern.c:1131 #10 0x000055555556950a in CairoOutputDev::drawImage (this=<optimized out>, state=0x5555557bcd70, ref=0x7fffffffd960, str=0x5555557bb9a0, widthA=<optimized out>, heightA=<optimized out>, colorMap=0x5555558012b0, interpolate=false, maskColors=0x0, inlineImg=false) at CairoOutputDev.cc:3265 #11 0x00007ffff7a618cd in Gfx::doImage (this=this@entry=0x5555557af5a0, ref=ref@entry=0x7fffffffd960, str=0x5555557bb9a0, inlineImg=inlineImg@entry=false) at Gfx.cc:4709 #12 0x00007ffff7a62ed9 in Gfx::opXObject (this=0x5555557af5a0, args=<optimized out>, numArgs=<optimized out>) at Gfx.cc:4208 #13 0x00007ffff7a5cd79 in Gfx::go (this=this@entry=0x5555557af5a0, topLevel=topLevel@entry=true) at Gfx.cc:763 #14 0x00007ffff7a5d18d in Gfx::display (this=this@entry=0x5555557af5a0, obj=obj@entry=0x7fffffffdd40, topLevel=topLevel@entry=true) at Gfx.cc:729 #15 0x00007ffff7aa5128 in Page::displaySlice (this=0x5555557a93e0, out=0x5555557a9d70, hDPI=72, vDPI=72, rotate=<optimized out>, useMediaBox=<optimized out>, crop=<optimized out>, sliceX=<optimized out>, sliceY=-1, sliceW=-1, sliceH=-1, printing=true, abortCheckCbk=0x0, abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at Page.cc:601 #16 0x000055555555fb61 in renderPage (output_h=842, output_w=595, page_h=<optimized out>, page_w=<optimized out>, pg=1, cairoOut=0x5555557a9d70, doc=0x5555557b0050) at pdftocairo.cc:673 #17 main (argc=3, argv=<optimized out>) at pdftocairo.cc:1197 (gdb)
Perhaps it would be more reasonable to file this bug under poppler component. If the underlying bug is in cairo lib, not pdftocairo, please route it back to cairo component? Thank you. -Alex
This bug is in the cairo backend component of poppler, in CairoOutputDev.cc:3090. 3087 buffer = cairo_image_surface_get_data (image); 3088 stride = cairo_image_surface_get_stride (image); 3089 for (int y = 0; y < height; y++) { 3090 uint32_t *dest = (uint32_t *) (buffer + y * stride); 3091 getRow(y, dest); 3092 } The vulnerability is an integer overflow with the operation y * stride is calculated. y and stride are signed int variables. So the y * stride can be overflown in certain situations. When this happens the result of y * stride is a negative number that gets added (subtracted) to buffer. The result is the variable data pointing to an invalid area and the program crashing. A possible fix is to replace: 3078 int stride; 3089 for (int y = 0; y < height; y++) { for: 3078 unsigned int stride; 3089 for (unsigned int y = 0; y < height; y++) {
ptrdiff_t would be better than unsigned to ensure it does not overflow on 64-bit. The bug also needs to be fixed in cairo (bug 98165).
Created attachment 135296 [details] [review] don't overflow y*stride on 64-bit The fix for cairo has been committed to master. Here is the corresponding fix for poppler. I'll push it out next week if there are no objections.
No objections.
Pushed
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.