New issue
Advanced search Search tips

Issue 786263 link

Starred by 1 user

Issue metadata

Status: Duplicate
Merged: issue 751423
Owner: ----
Closed: Nov 2017
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: ----
Type: Bug-Security



Sign in to add a comment

Security: Pdfium Heap Out Of Bounds Read in SkMatrix::setRSXform (Skia)

Reported by anikol...@sourcefire.com, Nov 17 2017

Issue description


VULNERABILITY DETAILS

Hello, normally we would be sending a full advisory via our Talos coordinator, but since this issue seems to be in (currently) non-default build we streamlined the process as we still think it's worth patching.

The bug itself is in Skia path drawing methods, specifically in SkMatrix::setRSXform() where an out of bounds read can manifest due to unchecked while loop in the caller at SkBaseDevice::drawTextRSXform(void const*, unsigned long, SkRSXform const*, SkPaint const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/core/SkDevice.cpp:481

    while ((const char*)text < (const char*)stopText) {
        localM.setRSXform(*xform++);
        currM.setConcat(this->ctm(), localM);
        SkAutoDeviceCTMRestore adc(this, currM);

        int subLen = proc((const char*)text);
        this->drawText(text, subLen, 0, 0, paint);
        text = (const char*)text + subLen;
    }

A text length discrepancy can cause `xform` above to be increased out of bounds. In the supplied PoC , xform is allocated for length 12 but will actually be increased up to 24 times in the above loop. 

This results in the following ASAN output:

=================================================================
==651==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60f000000780 at pc 0x000001d2834f bp 0x7ffcc72aaf20 sp 0x7ffcc72aaf18
READ of size 4 at 0x60f000000780 thread T0
    #0 0x1d2834e in SkMatrix::setRSXform(SkRSXform const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/core/SkMatrix.cpp:452
    #1 0x1d2834e in ?? ??:0
    #2 0x2103402 in SkBaseDevice::drawTextRSXform(void const*, unsigned long, SkRSXform const*, SkPaint const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/core/SkDevice.cpp:481
    #3 0x2103402 in ?? ??:0
    #4 0x20c0f45 in SkCanvas::onDrawTextRSXform(void const*, unsigned long, SkRSXform const*, SkRect const*, SkPaint const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/core/SkCanvas.cpp:2524
    #5 0x20c0f45 in ?? ??:0
    #6 0x20c34b3 in SkCanvas::drawTextRSXform(void const*, unsigned long, SkRSXform const*, SkRect const*, SkPaint const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/core/SkCanvas.cpp:2603
    #7 0x20c34b3 in ?? ??:0
    #8 0x2dae5f7 in SkiaState::FlushText() /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:936
    #9 0x2dae5f7 in ?? ??:0
    #10 0x2d99931 in Flush /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:1173
    #11 0x2d99931 in Flush /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:1549
    #12 0x2d99931 in ~CFX_SkiaDeviceDriver /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:1543
    #13 0x2d99931 in ?? ??:0
    #14 0x2d99bcd in CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:1542
    #15 0x2d99bcd in ?? ??:0
    #16 0x2dad3af in ~CFX_DefaultRenderDevice /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:2596
    #17 0x2dad3af in ~CFX_DefaultRenderDevice /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:2595
    #18 0x2dad3af in ?? ??:0
    #19 0x28f699f in operator() /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2272
    #20 0x28f699f in reset /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2585
    #21 0x28f699f in ~unique_ptr /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2539
    #22 0x28f699f in ~CPDF_PageRenderContext /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/cpdf_pagerendercontext.cpp:18
    #23 0x28f699f in ?? ??:0
    #24 0x292ec7b in operator() /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2272
    #25 0x292ec7b in reset /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2585
    #26 0x292ec7b in operator= /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../buildtools/third_party/libc++/trunk/include/memory:2451
    #27 0x292ec7b in SetRenderContext /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/page/cpdf_page.cpp:96
    #28 0x292ec7b in ?? ??:0
    #29 0x1cbc3fa in FPDF_RenderPage_Close /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../fpdfsdk/fpdf_progressive.cpp:109
    #30 0x1cbc3fa in ?? ??:0
    #31 0x4ff132 in (anonymous namespace)::RenderPage(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*, void*, (anonymous namespace)::FPDF_FORMFILLINFO_PDFiumTest*, int, (anonymous namespace)::Options const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1282
    #32 0x4ff132 in ?? ??:0
    #33 0x4f7894 in RenderPdf /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1469
    #34 0x4f7894 in main /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1630
    #35 0x4f7894 in ?? ??:0
    #36 0x7fda3dfa682f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291
    #37 0x7fda3dfa682f in ?? ??:0

0x60f000000780 is located 0 bytes to the right of 176-byte region [0x60f0000006d0,0x60f000000780)
allocated by thread T0 here:
    #0 0x4c7232 in __interceptor_realloc ??:?
    #1 0x4c7232 in ?? ??:0
    #2 0x1e287fd in sk_realloc_throw(void*, unsigned long) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/src/ports/SkMemory_malloc.cpp:63
    #3 0x1e287fd in ?? ??:0
    #4 0x2d9c317 in resizeStorageToAtLeast /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/include/pathops/../private/SkTDArray.h:384
    #5 0x2d9c317 in setCount /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../third_party/skia/include/pathops/../private/SkTDArray.h:156
    #6 0x2d9c317 in DrawText /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:864
    #7 0x2d9c317 in ?? ??:0
    #8 0x2d99ea5 in CFX_SkiaDeviceDriver::DrawDeviceText(int, FXTEXT_CHARPOS const*, CFX_Font*, CFX_Matrix const*, float, unsigned int) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/skia/fx_skia_device.cpp:1558
    #9 0x2d99ea5 in ?? ??:0
    #10 0x2d360e7 in CFX_RenderDevice::DrawNormalText(int, FXTEXT_CHARPOS const*, CFX_Font*, float, CFX_Matrix const*, unsigned int, unsigned int) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fxge/cfx_renderdevice.cpp:878
    #11 0x2d360e7 in ?? ??:0
    #12 0x29f6c51 in CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice*, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, std::__1::vector<float, std::__1::allocator<float> > const&, CPDF_Font*, float, CFX_Matrix const*, unsigned int, CPDF_RenderOptions const*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/render/cpdf_textrenderer.cpp:155
    #13 0x29f6c51 in ?? ??:0
    #14 0x29d1b36 in CPDF_RenderStatus::ProcessText(CPDF_TextObject*, CFX_Matrix const*, CFX_PathData*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/render/cpdf_renderstatus.cpp:1816
    #15 0x29d1b36 in ?? ??:0
    #16 0x29cfa10 in CPDF_RenderStatus::ProcessObjectNoClip(CPDF_PageObject*, CFX_Matrix const*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/render/cpdf_renderstatus.cpp:1173
    #17 0x29cfa10 in ?? ??:0
    #18 0x29d00b6 in CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject*, CFX_Matrix const*, IFX_PauseIndicator*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/render/cpdf_renderstatus.cpp:1129
    #19 0x29d00b6 in ?? ??:0
    #20 0x29c85bc in CPDF_ProgressiveRenderer::Continue(IFX_PauseIndicator*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../core/fpdfapi/render/cpdf_progressiverenderer.cpp:93
    #21 0x29c85bc in ?? ??:0
    #22 0x1cc892d in (anonymous namespace)::RenderPageImpl(CPDF_PageRenderContext*, CPDF_Page*, CFX_Matrix const&, FX_RECT const&, int, bool, IFSDK_PAUSE_Adapter*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../fpdfsdk/fpdfview.cpp:129
    #23 0x1cc892d in ?? ??:0
    #24 0x1cc832e in FPDF_RenderPage_Retail(CPDF_PageRenderContext*, void*, int, int, int, int, int, int, bool, IFSDK_PAUSE_Adapter*) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../fpdfsdk/fpdfview.cpp:1266
    #25 0x1cc832e in ?? ??:0
    #26 0x1cbbec6 in FPDF_RenderPageBitmap_Start /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../fpdfsdk/fpdf_progressive.cpp:60
    #27 0x1cbbec6 in ?? ??:0
    #28 0x4ff091 in (anonymous namespace)::RenderPage(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*, void*, (anonymous namespace)::FPDF_FORMFILLINFO_PDFiumTest*, int, (anonymous namespace)::Options const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1273
    #29 0x4ff091 in ?? ??:0
    #30 0x4f7894 in RenderPdf /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1469
    #31 0x4f7894 in main /ramdisk/chrome_build/pdfium/pdfium/out/Default/../../samples/pdfium_test.cc:1630
    #32 0x4f7894 in ?? ??:0
    #33 0x7fda3dfa682f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291
    #34 0x7fda3dfa682f in ?? ??:0

SUMMARY: AddressSanitizer: heap-buffer-overflow (/ramdisk/chrome_build/pdfium/pdfium/out/Default/pdfium_test+0x1d2834e)
Shadow bytes around the buggy address:
  0x0c1e7fff80a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff80b0: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
  0x0c1e7fff80c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff80d0: fd fd fa fa fa fa fa fa fa fa 00 00 00 00 00 00
  0x0c1e7fff80e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c1e7fff80f0:[fa]fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c1e7fff8100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c1e7fff8110: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff8120: 00 00 00 00 00 00 00 00 00 00 04 fa fa fa fa fa
  0x0c1e7fff8130: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff8140: 00 00 00 00 00 00 00 00 00 00 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
==651==ABORTING


The required build configuration differs from default in that Skia support needs to be enabled. 



VERSION
PDFium current master branch (latest at time of writing ec2209da158750beeeaeaab5dd68e58424921c4a) 
Operating System: Linux x64

REPRODUCTION CASE
simply opening the supplied poc with pdfium_test crashes.



Cheers,
Aleks 
 
pdfium_rsxform_oob.pdf
970 bytes Download
Project Member

Comment 1 by ClusterFuzz, Nov 17 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://clusterfuzz.com/testcase?key=5175866782121984.
Project Member

Comment 2 by ClusterFuzz, Nov 17 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://clusterfuzz.com/testcase?key=5666532033298432.

Comment 3 by mmoroz@chromium.org, Nov 17 2017

Mergedinto: 751423
Status: Duplicate (was: Unconfirmed)
Project Member

Comment 4 by sheriffbot@chromium.org, Nov 10

Labels: -Restrict-View-SecurityTeam allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment