New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 601362 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Closed: Apr 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug-Security



Sign in to add a comment

Security: PDFium Out-of-Bounds Read in CFX_FaceCache::RenderGlyph

Reported by stackexp...@gmail.com, Apr 7 2016

Issue description

VULNERABILITY DETAILS
The attached proof-of-concept file could crash the latest build of pdfium_test.
This is an Out-Of-Bounds Read issue.
The exception information is presented as follows.

-----------------------
Exception Information
-----------------------
(14e4.2bac): Access violation - code c0000005 (!!! second chance !!!)
eax=80fcb76f ebx=0816afe8 ecx=80000001 edx=00002c13 esi=07f37f78 edi=07dd7fd8
eip=00e2933c esp=003cf4cc ebp=003cf52c iopl=0         ov up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010a97
pdfium_test!CFX_FaceCache::RenderGlyph+0xec:
00e2933c 0fbe08          movsx   ecx,byte ptr [eax]       ds:002b:80fcb76f=??

Here we can see that the process tried to read data from 0x80fcb76f. It's known to all that an user mode application cannot access memory address which is greater than 0x80000000.

-----------------------
Stack Trace Information
-----------------------
0:000> k
ChildEBP RetAddr  
003cf52c 00e291c6 pdfium_test!CFX_FaceCache::RenderGlyph+0xec [pdfium\core\fxge\ge\fx_ge_text.cpp @ 1571]
003cf560 00e28d7b pdfium_test!CFX_FaceCache::LookUpGlyphBitmap+0xd6 [pdfium\core\fxge\ge\fx_ge_text.cpp @ 1306]
003cf62c 00e25fd1 pdfium_test!CFX_FaceCache::LoadGlyphBitmap+0x14b [pdfium\core\fxge\ge\fx_ge_text.cpp @ 1407]
003cf794 00d5faf8 pdfium_test!CFX_RenderDevice::DrawNormalText+0x521 [pdfium\core\fxge\ge\fx_ge_text.cpp @ 307]
003cf7d8 00d6078b pdfium_test!CPDF_TextRenderer::DrawNormalText+0xc8 [pdfium\core\fpdfapi\fpdf_render\fpdf_render_text.cpp @ 727]
003cf870 00d46c64 pdfium_test!CPDF_RenderStatus::ProcessText+0x1eb [pdfium\core\fpdfapi\fpdf_render\fpdf_render_text.cpp @ 319]
003cf890 00d451fc pdfium_test!CPDF_RenderStatus::ProcessObjectNoClip+0x34 [pdfium\core\fpdfapi\fpdf_render\fpdf_render.cpp @ 397]
003cf8ac 00d44fee pdfium_test!CPDF_RenderStatus::ContinueSingleObject+0xec [pdfium\core\fpdfapi\fpdf_render\fpdf_render.cpp @ 339]
003cf900 00d194f1 pdfium_test!CPDF_ProgressiveRenderer::Continue+0x2de [pdfium\core\fpdfapi\fpdf_render\fpdf_render.cpp @ 1103]
003cf93c 00d19d99 pdfium_test!FPDF_RenderPage_Retail+0x221 [pdfium\fpdfsdk\fpdfview.cpp @ 936]
003cf978 00d13168 pdfium_test!FPDF_RenderPageBitmap+0x99 [pdfium\fpdfsdk\fpdfview.cpp @ 668]
003cfa94 00d1355f pdfium_test!RenderPage+0x1b8 [pdfium\samples\pdfium_test.cc @ 452]
003cfb6c 00d18696 pdfium_test!RenderPdf+0x2ef [pdfium\samples\pdfium_test.cc @ 628]
003cfc50 00e5478d pdfium_test!main+0x2e6 [pdfium\samples\pdfium_test.cc @ 877]
(Inline) -------- pdfium_test!invoke_main+0x1d [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 74]
003cfc9c 7647338a pdfium_test!__scrt_common_main_seh+0xff [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 264]
003cfca8 76ef9a02 kernel32!BaseThreadInitThunk+0xe
003cfce8 76ef99d5 ntdll!__RtlUserThreadStart+0x70
003cfd00 00000000 ntdll!_RtlUserThreadStart+0x1b

The topmost stack frame is located at function CFX_FaceCache::RenderGlyph().

-----------------------
Source Code Analysis
-----------------------
1545 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont,
1546                                             uint32_t glyph_index,
1547                                             FX_BOOL bFontStyle,
1548                                             const CFX_Matrix* pMatrix,
1549                                             int dest_width,
1550                                             int anti_alias) {
1551   if (!m_Face) {
1552     return NULL;
1553   }
1554   FXFT_Matrix ft_matrix;
1555   ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
1556   ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
1557   ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
1558   ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
1559   FX_BOOL bUseCJKSubFont = FALSE;
1560   const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
1561   if (pSubstFont) {
1562     bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle;
1563     int skew = 0;
1564     if (bUseCJKSubFont) {
1565       skew = pSubstFont->m_bItlicCJK ? -15 : 0;
1566     } else {
1567       skew = pSubstFont->m_ItalicAngle;
1568     }
1569     if (skew) {
1570       // skew is nonpositive so -skew is used as the index.
1571       skew = -skew <= static_cast<int>(ANGLESKEW_ARRAY_SIZE) // Crashed at this line!
1572                  ? -58                                       // Crashed at this line!
1573                  : -g_AngleSkew[-skew];                      // Crashed at this line!
1574       if (pFont->IsVertical())
1575         ft_matrix.yx += ft_matrix.yy * skew / 100;
1576       else
1577         ft_matrix.xy += -ft_matrix.xx * skew / 100;
1578     }
1579     if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
1580       pFont->AdjustMMParams(glyph_index, dest_width,
1581                             pFont->GetSubstFont()->m_Weight);
1582     }
1583   }

0:000> dv
            this = 0x0816afe8
           pFont = 0x07f37f78
     glyph_index = 0
      bFontStyle = 0n0
         pMatrix = 0x003cf6b0
      dest_width = 0n615
      anti_alias = 0n3
  bUseCJKSubFont = 0n0
scoped_transform = class `anonymous-namespace'::ScopedFontTransform
      load_flags = <value unavailable>
        pDestBuf = <value unavailable>
      dest_pitch = <value unavailable>
    pGlyphBitmap = <value unavailable>
       src_pitch = <value unavailable>
       ft_matrix = struct FT_Matrix_
          weight = <value unavailable>
         bmwidth = <value unavailable>
           error = <value unavailable>
        bmheight = <value unavailable>
      pSubstFont = 0x07dd7fd8
         pSrcBuf = <value unavailable>
            skew = 0n-2147483647              <- (ecx, 0x80000001)
           index = <value unavailable>
           level = <value unavailable>
           bytes = <value unavailable>
               n = <value unavailable>
        rowbytes = <value unavailable>

-----------------------
Vulnerability Analysis
-----------------------
0:000> ub eip
pdfium_test!CFX_FaceCache::RenderGlyph+0xd5 [pdfium\core\fxge\ge\fx_ge_text.cpp @ 1571]:
00e29325 8bc1            mov     eax,ecx
00e29327 f7d8            neg     eax
00e29329 83f81e          cmp     eax,1Eh
00e2932c 7f07            jg      pdfium_test!CFX_FaceCache::RenderGlyph+0xe5 (00e29335)
00e2932e b9c6ffffff      mov     ecx,0FFFFFFC6h
00e29333 eb0c            jmp     pdfium_test!CFX_FaceCache::RenderGlyph+0xf1 (00e29341)
00e29335 b870b7fc00      mov     eax,offset pdfium_test!g_AngleSkew (00fcb770)
00e2933a 2bc1            sub     eax,ecx

0:000> db 00fcb770
00fcb770  00 02 03 05 07 09 0b 0c-0e 10 12 13 15 17 19 1b  ................
00fcb780  1d 1f 20 22 24 26 28 2a-2d 2f 31 33 35 37 00 00  .. "$&(*-/1357..
00fcb790  00 03 06 07 08 09 0b 0c-0e 0f 10 11 12 13 14 15  ................
00fcb7a0  16 17 18 19 1a 1b 1c 1d-1e 1f 20 21 22 23 23 24  .......... !"##$
00fcb7b0  24 25 25 25 26 26 26 27-27 27 28 28 28 29 29 29  $%%%&&&'''((()))
00fcb7c0  2a 2a 2a 2a 2b 2b 2b 2c-2c 2c 2c 2d 2d 2d 2d 2e  ****+++,,,,----.
00fcb7d0  2e 2e 2e 2f 2f 2f 2f 30-30 30 30 30 31 31 31 31  ...////000001111
00fcb7e0  32 32 32 32 32 33 33 33-33 33 34 34 34 34 34 35  2222233333444445

Function CFX_FaceCache::RenderGlyph starts from the 1545th line of file pdfium\core\fxge\ge\fx_ge_text.cpp. We can see that the type of skew is int and the value is -2147483647 (ecx, 0x80000001). It's no doublt that the expression g_AngleSkew[-skew] will cause an Out-of-Bounds Read issue.

The value of g_AngleSkew is 00fcb770. The value of skew can be controlled by the attacker! In the attached proof-of-concept file, the /ItalicAngle property of the 9th object was set to 2147483649 (0x80000001). You can change this value to anything you like. It seems that we can read data from arbitrary memory address.

9 0 obj
<<
    /Type /FontDescriptor
    /FontName /GMTXSU+Calibri
    /FontBBox [0 -177 770 680]
    /Flags 4
    /Ascent 680
    /CapHeight 680
    /Descent -177
    /ItalicAngle 2147483649
    /StemV 115
    /MissingWidth 506
    /FontFile2 12 0 R
>>
endobj

The /FontFile2 property of the 9th object is 12 0 R. The 12th object uses the /FlateDecode filter.

12 0 obj
<<
    /Filter /FlateDecode
    /Length1 26888
    /Length 10903
>>

To trigger this vulnerability, we should mutate the value of the compressed content. Here the 110th byte of the compressed content was changed from 0x37 to 0x39. The mutated compressed content cannot be decompressed normally (tested with zlib library delivered with python).I'm not sure how PDFium handle this situation.

stream
78 9C ED 7D 09 7C 54 D5 D9 F7 39 F7 CE BE 64 F6
C9 24 93 64 66 32 C9 24 61 B2 90 7D 21 24 43 36
48 42 08 21 19 48 80 40 42 C2 AA 6C 01 64 11 14
C1 35 8A BB 56 D4 BA B4 2A 56 14 26 C3 16 C4 56
6C 51 5B 5B D4 BA B7 2E C5 B6 56 A4 62 B1 AD 2B
26 F9 9E 73 9F 7B 30 F0 AA 5F DF 7E FD 7E 7D FB
7D CC CD FF FE FF E7 39 CB DC FB 9C ED B9 [39]    // 0x37 -> 0x39
......
endstream

-----------------------
Patch Suggestion
-----------------------
Maybe we should check if the value of /ItalicAngle is valid or not.

-----------------------
Credit
-----------------------
This vulnerability was discovered by Ke Liu of Tencent's Xuanwu LAB (http://www.tencent.com/).

VERSION
Chrome Version: [x.x.x.x] + [stable, beta, or dev]
PDFium Version: latest version built with Visual Studio 2015, both xfa and javascript were disabled.
Operating System: [Windows 7 SP1]

REPRODUCTION CASE
Both of the original normal pdf document and the mutated pdf document were attached.

FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION
See at section VULNERABILITY DETAILS.

 
Function CFX_Font::LoadGlyphPath() at line 1827 may also be vulnerable to issue.

Comment 2 by kenrb@chromium.org, Apr 8 2016

Components: Internals>Plugins>PDF
Labels: Security_Severity-Medium Security_Impact-Stable OS-All Pri-1
Owner: och...@chromium.org
Status: Assigned (was: Unconfirmed)
Thanks for the report.

ochang@: Are you available to look into this?
Project Member

Comment 3 by ClusterFuzz, Apr 8 2016

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=5760321024688128
Project Member

Comment 4 by ClusterFuzz, Apr 8 2016

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=6474405881839616

Fuzzer: ifratric_pdf_generic
Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x0000907ca194
Crash State:
  CFX_FaceCache::RenderGlyph
  CFX_FaceCache::LookUpGlyphBitmap
  CFX_FaceCache::LoadGlyphBitmap
  
Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=383194:384397

Minimized Testcase (215.17 Kb): https://cluster-fuzz.appspot.com/download/AMIfv95ORS_teR00RaT7d7NdLBcg1xoin-8uBFAkvngjaVxdvi_DtSB6xeB_0h2KEfz4kJCitTrh7AzhQ-AD50zJgcsu35yW6TNVJ01pwLrtO9KpyYcAc-76Yrej-BSI45llt3WJ132AaplQuPPJ7CW_PV8c20TdM19rXcAJlVk6VlcfsE_0qpM

Filer: ochang

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
Looks like this was found by an internal fuzzer on April 1.
Labels: -Security_Impact-Stable Security_Impact-Head

Comment 7 by kenrb@chromium.org, Apr 8 2016

Labels: M-50
Project Member

Comment 8 by ClusterFuzz, Apr 8 2016

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5760321024688128

Uploader: ochang@google.com
Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x0000907ca793
Crash State:
  CFX_FaceCache::RenderGlyph
  CFX_FaceCache::LookUpGlyphBitmap
  CFX_FaceCache::LoadGlyphBitmap
  
Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=383194:384397

Minimized Testcase (13.98 Kb): https://cluster-fuzz.appspot.com/download/AMIfv95gdtM9jVTcegWHIyCSiaXObmF0IrjvxGrxMyr1sKYp6D9Pc-sCErlD6zD19-vzKlbOmPMKFiZMp7_WIKtKKBVgLxWfPj9DCFgZgo_Al7H0kqs9sxjfrutKQoTXofVUWgF8edB0xfE0mkjcfu2Dzahf6uKzrw

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
Project Member

Comment 9 by sheriffbot@chromium.org, Apr 8 2016

Labels: -Security_Impact-Head Security_Impact-Beta
Labels: -M-50 -Security_Impact-Beta M-51 Security_Impact-Head
Fixing impact/milestone.
Cc: och...@chromium.org
 Issue 602129  has been merged into this issue.
 Issue 602117  has been merged into this issue.
Cc: weili@chromium.org
Labels: Merge-Request-51
Status: Fixed (was: Assigned)
Requesting merge to 51 since this didn't make the cut.

Comment 17 by tin...@google.com, Apr 12 2016

Labels: -Merge-Request-51 Merge-Review-51 Hotlist-Merge-Review
[Automated comment] DEPS changes referenced in bugdroid comments, needs manual review.
Project Member

Comment 18 by ClusterFuzz, Apr 13 2016

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 19 by ClusterFuzz, Apr 13 2016

ClusterFuzz has detected this issue as fixed in range 386714:386879.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5760321024688128

Uploader: ochang@google.com
Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x0000907ca793
Crash State:
  CFX_FaceCache::RenderGlyph
  CFX_FaceCache::LookUpGlyphBitmap
  CFX_FaceCache::LoadGlyphBitmap
  
Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=383194:384397
Fixed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=386714:386879

Minimized Testcase (13.98 Kb): https://cluster-fuzz.appspot.com/download/AMIfv95gdtM9jVTcegWHIyCSiaXObmF0IrjvxGrxMyr1sKYp6D9Pc-sCErlD6zD19-vzKlbOmPMKFiZMp7_WIKtKKBVgLxWfPj9DCFgZgo_Al7H0kqs9sxjfrutKQoTXofVUWgF8edB0xfE0mkjcfu2Dzahf6uKzrw

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Project Member

Comment 20 by ClusterFuzz, Apr 13 2016

ClusterFuzz has detected this issue as fixed in range 386714:386879.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=6474405881839616

Fuzzer: ifratric_pdf_generic
Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x0000907ca194
Crash State:
  CFX_FaceCache::RenderGlyph
  CFX_FaceCache::LookUpGlyphBitmap
  CFX_FaceCache::LoadGlyphBitmap
  
Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=383194:384397
Fixed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=386714:386879

Minimized Testcase (215.17 Kb): https://cluster-fuzz.appspot.com/download/AMIfv95ORS_teR00RaT7d7NdLBcg1xoin-8uBFAkvngjaVxdvi_DtSB6xeB_0h2KEfz4kJCitTrh7AzhQ-AD50zJgcsu35yW6TNVJ01pwLrtO9KpyYcAc-76Yrej-BSI45llt3WJ132AaplQuPPJ7CW_PV8c20TdM19rXcAJlVk6VlcfsE_0qpM

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Project Member

Comment 21 by ClusterFuzz, Apr 14 2016

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5760321024688128

Uploader: ochang@google.com
Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x0000907ca793
Crash State:
  CFX_FaceCache::RenderGlyph
  CFX_FaceCache::LookUpGlyphBitmap
  CFX_FaceCache::LoadGlyphBitmap
  
Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=383194:384397
Fixed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=386714:386879

Minimized Testcase (13.98 Kb): https://cluster-fuzz.appspot.com/download/AMIfv95gdtM9jVTcegWHIyCSiaXObmF0IrjvxGrxMyr1sKYp6D9Pc-sCErlD6zD19-vzKlbOmPMKFiZMp7_WIKtKKBVgLxWfPj9DCFgZgo_Al7H0kqs9sxjfrutKQoTXofVUWgF8edB0xfE0mkjcfu2Dzahf6uKzrw

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
Labels: -Merge-Review-51 Merge-Approved-51
Merge approved for M51 (branch 2704)
Please merge your change to M51 branch 2704 ASAP (before 6:00 PM PST, today) so we can take it in for M51 last Dev release tomorrow.
Project Member

Comment 24 by bugdroid1@chromium.org, Apr 18 2016

Labels: -merge-approved-51 merge-merged-2704
The following revision refers to this bug:
  http://goto.ext.google.com/viewvc/chrome-internal?view=rev&revision=86732

------------------------------------------------------------------
r86732 | ochang@google.com | 2016-04-18T19:53:43.499907Z

-----------------------------------------------------------------
Cc: timwillis@chromium.org
Labels: -Security_Impact-Head reward-topanel Security_Impact-Stable Release-0-M51
Updating labels based on #22/#23
Labels: -reward-topanel CVE-2016-1685 reward-unpaid reward-1000
Thanks for reporting this issue. Our reward panel decided to award you $1,000 for this report. Congratulations!

We've credited you in our release notes as "Ke Liu of Tencent's Xuanwu LAB": https://googlechromereleases.blogspot.com/2016/05/stable-channel-update_25.html

Someone from our finance team will be in contact to collect details for payment within 7 days. If that doesn't happen, please either update this bug or contact me at timwillis@.

The CVE-ID for this issue is CVE-2016-1685. Usual boilerplate text below - let me know if you have any questions.

Thanks again for the report!


*** Boilerplate reminders! ***
Please do NOT publicly disclose details until a fix has been released to all our users. Early public disclosure may cancel the provisional reward. Also, please be considerate about disclosure when the bug affects a core library that may be used by other products. Please do NOT share this information with third parties who are not directly involved in fixing the bug. Doing so may cancel the provisional reward. Please be honest if you have already disclosed anything publicly or to third parties. Lastly, we understand that some of you are not interested in money. We offer the option to donate your reward to an established charity. If you prefer this option, let us know and we will also match your donation - subject to our discretion. Any rewards that are unclaimed after 12 months will be donated to a charity of our choosing.
Hi Timwillis, no one has contacted me so far.
Thanks for letting me know - I'll chase today along with  Issue 603518 .
Labels: -reward-unpaid reward-inprocess
Project Member

Comment 30 by sheriffbot@chromium.org, Jul 20 2016

Labels: -Restrict-View-SecurityNotify
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
Project Member

Comment 31 by sheriffbot@chromium.org, Oct 1 2016

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
Project Member

Comment 32 by sheriffbot@chromium.org, Oct 2 2016

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
Labels: allpublic
Labels: CVE_description-submitted

Sign in to add a comment