High patch-now ~ plausible CVSS 8.8 chrome OOB 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactHeap buffer overflow in PDFium
DescriptionHeap buffer overflow in PDFium
ComponentPDFium
Bug ClassOOB
Action tierpatch-now — corruption primitive, file-reachable in default config (plausible) — upheld by independent review by AI
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Independent review by AIPlausible
Reviewer notes: Overflow trigger not provable from diff: new_bitmap sizing isn't shown, and the commit is a spanify refactor converting any OOB write into a deterministic trap rather than adding an explicit bounds check. Claim flags these as inferred.
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker488585504
Fix commit1765e514c52f (pdfium) +21/-21
CWECWE-122 (Heap buffer overflow)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
Creditedc6eed09fc8b174b0f3eebedcceb1e792
Reported2026-03-01 (per vendor advisory)
Fix landed2026-03-02 (public git)
Disclosed2026-03-18
Patch gap16 days — fix public in source before the advisory

Background

`CFX_Face::RenderGlyph()`
the PDFium routine (named in the commit subject) that asks FreeType to rasterize a glyph and copies the resulting ft_bitmap into a newly created PDFium bitmap (new_bitmap) for text rendering.
`FT_PIXEL_MODE_MONO` / `FontAntiAliasingMode`
FreeType’s 1-bit-per-pixel glyph format versus PDFium’s requested anti-aliasing mode; when PDFium wants grayscale or LCD (kLcd, 3 bytes per pixel) output but FreeType returns a mono bitmap, PDFium expands each source bit into 1 or 3 destination bytes.
`dest_pitch`
the row stride (GetPitch()) of the destination bitmap; destination offsets are computed as row * dest_pitch + column_offset.
Spanification (`pdfium::span`, `UNSAFE_TODO`)
PDFium’s migration from raw pointers to bounds-checked spans; UNSAFE_TODO marks code that still performs unchecked pointer arithmetic.

Root Cause Analysis

Verify before building a PoC

This analysis is consistent with the fixing commit but not fully provable from it: part of the vulnerable path lives in code the fix commit does not touch. Confirm the trigger and the sink against the source before relying on it for exploit development.
What the commit does not establish: Overflow trigger not provable from diff: new_bitmap sizing isn't shown, and the commit is a spanify refactor converting any OOB write into a deterministic trap rather than adding an explicit bounds check. Claim flags these as inferred.

The hunk sits in the glyph-copy tail of the function the commit subject identifies as CFX_Face::RenderGlyph() (the @@ header itself carries no function name). Before the patch, the whole copy was wrapped in UNSAFE_TODO and wrote through a raw uint8_t* pDestBuf obtained from new_bitmap->GetWritableBuffer().data(): the mono-expansion loop wrote pDestBuf[i * dest_pitch + n * bytes + b] for every i < ft_bitmap.rows, n < ft_bitmap.width, b < bytes (with bytes = 3 in LCD mode), and the other branch did FXSYS_memset(pDestBuf, 0, dest_pitch * ft_bitmap.rows) plus per-row FXSYS_memcpy of rowbytes. None of these writes was checked against the actual size of the destination buffer, so the code relied on the unstated invariant that new_bitmap is at least ft_bitmap.rows rows tall and wide enough for ft_bitmap.width * bytes bytes per row; if FreeType’s reported glyph dimensions exceed the allocated destination (how new_bitmap is sized is not shown in the diff), the writes run past the heap allocation, matching the advisory’s “heap buffer overflow”.

The fix does not change the index arithmetic or add an explicit dimension check; instead it holds the destination as pdfium::span<uint8_t> dest_span and routes every write through checked span operations (dest_span[...], std::ranges::fill(dest_span.first(...)), fxcrt::spancpy(dest_span.subspan(...), ...)), so any out-of-range destination access now traps deterministically instead of corrupting the heap. Note that the source reads from pSrcBuf (FreeType’s buffer) remain under UNSAFE_TODO and are still unchecked.

Key insight
Destination writes into the glyph bitmap were computed from FreeType’s glyph geometry (ft_bitmap.rows, ft_bitmap.width, ft_bitmap.pitch) but performed through an unchecked raw pointer, so a geometry/allocation mismatch became a heap overflow. The fix makes the destination a bounds-checked pdfium::span, converting any such overflow into a safe crash.

Attack Path

  1. Deliver a crafted PDF the attacker gets the victim to open a PDF (e.g. in Chrome’s built-in PDF viewer) whose text uses an attacker-supplied embedded font.
  2. Glyph rasterization PDFium renders text and calls into the glyph-rendering path, which has FreeType rasterize the glyph and produce ft_bitmap.
  3. Mismatched geometry the font/glyph is shaped so that FreeType’s bitmap dimensions (rows, width, or a mono bitmap expanded ×3 in LCD mode) exceed what the destination new_bitmap was allocated for (inferred; the sizing logic is not in the diff).
  4. Heap overflow the unchecked loop, FXSYS_memset, or FXSYS_memcpy writes past the end of the destination bitmap buffer, corrupting adjacent heap memory (what lies there is inferred).

Impact Assessment

An attacker gains an out-of-bounds heap write in PDFium, which in Chrome runs inside the sandboxed renderer process hosting the PDF; turning it into code execution in that renderer is (inferred). Preconditions are that the victim opens or is navigated to an attacker-controlled PDF (PDF rendering is enabled in a stock build) and that the embedded font yields a glyph whose dimensions trigger the mismatch (inferred); no flag or extension is required as far as the diff shows. The vendor rates this as high severity; the advisory provided does not state in-the-wild exploitation.

Changed Functions

FunctionChangeNotes
for
core/fxge/cfx_face.cpp
modified

Files Changed

  • core/fxge/cfx_face.cpp

Audit Directions

  • Remaining `UNSAFE_TODO` source reads
    the pSrcBuf[i * ft_bitmap.pitch + n / 8] read and the pdfium::span(pSrcBuf + row * ft_bitmap.pitch, rowbytes) construction are still unchecked; audit them (including negative ft_bitmap.pitch handling, given the abs() use) for out-of-bounds reads of FreeType’s buffer.
  • Producer/consumer geometry mismatches
    look for other places in core/fxge (and other font backends) that size a CFX_DIBitmap from one set of dimensions and then fill it using FreeType-reported rows/width/pitch or an anti-aliasing byte multiplier.
  • Raw-pointer pixel loops
    grep PDFium for GetWritableBuffer().data() and UNSAFE_TODO blocks that perform row * pitch + col * bpp arithmetic, and prioritise them for spanification.
From 1765e514c52f0bbda24041e37fd1c61d09bda831 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@google.com>
Date: Mon, 02 Mar 2026 12:07:47 -0800
Subject: [PATCH] Spanify more of CFX_Face::RenderGlyph().

Bug: 488585504
Change-Id: I0a7baff50edddb58f5c73193c38ce5e38b6930d3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/144030
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
---

diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index 59c5fb2..235f6ce 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -596,31 +596,31 @@
       glyph->bitmap_left, glyph->bitmap_top, new_bitmap);
 
   const int dest_pitch = new_bitmap->GetPitch();
-  uint8_t* pDestBuf = new_bitmap->GetWritableBuffer().data();
+  pdfium::span<uint8_t> dest_span = new_bitmap->GetWritableBuffer();
   const uint8_t* pSrcBuf = ft_bitmap.buffer;
-  UNSAFE_TODO({
-    if (anti_alias != FontAntiAliasingMode::kMono &&
-        ft_bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
-      unsigned int bytes = anti_alias == FontAntiAliasingMode::kLcd ? 3 : 1;
-      for (unsigned int i = 0; i < ft_bitmap.rows; i++) {
-        for (unsigned int n = 0; n < ft_bitmap.width; n++) {
-          uint8_t data =
-              (pSrcBuf[i * ft_bitmap.pitch + n / 8] & (0x80 >> (n % 8))) ? 255
-                                                                         : 0;
-          for (unsigned int b = 0; b < bytes; b++) {
-            pDestBuf[i * dest_pitch + n * bytes + b] = data;
-          }
+  if (anti_alias != FontAntiAliasingMode::kMono &&
+      ft_bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
+    unsigned int bytes = anti_alias == FontAntiAliasingMode::kLcd ? 3 : 1;
+    for (unsigned int i = 0; i < ft_bitmap.rows; i++) {
+      for (unsigned int n = 0; n < ft_bitmap.width; n++) {
+        uint8_t data = (UNSAFE_TODO(pSrcBuf[i * ft_bitmap.pitch + n / 8]) &
+                        (0x80 >> (n % 8)))
+                           ? 255
+                           : 0;
+        for (unsigned int b = 0; b < bytes; b++) {
+          dest_span[i * dest_pitch + n * bytes + b] = data;
         }
       }
-    } else {
-      FXSYS_memset(pDestBuf, 0, dest_pitch * ft_bitmap.rows);
-      int rowbytes = std::min(abs(ft_bitmap.pitch), dest_pitch);
-      for (unsigned int row = 0; row < ft_bitmap.rows; row++) {
-        FXSYS_memcpy(pDestBuf + row * dest_pitch,
-                     pSrcBuf + row * ft_bitmap.pitch, rowbytes);
-      }
     }
-  });
+  } else {
+    std::ranges::fill(dest_span.first(dest_pitch * ft_bitmap.rows), 0);
+    int rowbytes = std::min(abs(ft_bitmap.pitch), dest_pitch);
+    for (unsigned int row = 0; row < ft_bitmap.rows; row++) {
+      fxcrt::spancpy(dest_span.subspan(row * dest_pitch),
+                     UNSAFE_TODO(pdfium::span(pSrcBuf + row * ft_bitmap.pitch,
+                                              static_cast<size_t>(rowbytes))));
+    }
+  }
   return pGlyphBitmap;
 }
 
Loading diff…

Original Bug Report

reported by je...@gmail.com

Heap buffer overflow in CFX_Face::RenderGlyph when expanding MONO bitmap glyphs under LCD anti-aliasing

Heap buffer overflow in CFX_Face::RenderGlyph when expanding MONO bitmap glyphs under LCD anti-aliasing

Summary

A heap buffer overflow exists in PDFium’s glyph rendering code. When a PDF embeds a bitmap-only TrueType font (containing EBDT/EBLC tables but no glyf outlines), FreeType loads glyphs as monochrome bitmaps regardless of the FT_LOAD_NO_BITMAP flag. The subsequent call to FT_Render_Glyph silently succeeds without converting the bitmap pixel format. CFX_Face::RenderGlyph then expands each monochrome pixel into 3 bytes for LCD anti-aliasing, but the destination buffer was allocated assuming 1 byte per pixel. This causes a write that overflows the heap buffer by approximately 2 * bitmap_width - 4 bytes. The bug affects all platforms where Chrome uses the AGG renderer for PDF text (Linux, Windows, Android), which is the default configuration. No user interaction beyond opening a PDF is required.

Bisect

Introducing Commit: 5110c4743751145c4ae1934cd1d83bc6c55bb43f

  • Date: 2014-05-17
  • Author: John Abd-El-Malek
  • Review: Initial PDFium commit

The vulnerable MONO-to-LCD expansion logic has been present since PDFium’s initial open-source commit. The code was originally in CFX_FaceCache::RenderGlyph (later renamed CFX_GlyphCache) and was moved into CFX_Face::RenderGlyph in commit 65dc04ddae82f565c0d77dcdefca592b15a2bce4 (2023-12-16, CL https://pdfium-review.googlesource.com/c/pdfium/+/114790) by Lei Zhang.

Root Cause

The vulnerability is in CFX_Face::RenderGlyph, which handles the conversion of FreeType glyph bitmaps into PDFium’s internal CFX_GlyphBitmap format. When the requested anti-aliasing mode is LCD (FontAntiAliasingMode::kLcd) but FreeType returns a monochrome bitmap (FT_PIXEL_MODE_MONO), the code attempts to expand each source pixel into 3 destination bytes without adjusting the destination buffer width.

The buffer allocation uses the raw bitmap width in pixels, creating a k8bppMask format bitmap (1 byte per pixel):

// cfx_face.cpp:586-592
int dib_width = bitmap.width;
auto pGlyphBitmap =
    std::make_unique<CFX_GlyphBitmap>(glyph->bitmap_left, glyph->bitmap_top);
const FXDIB_Format format = anti_alias == FontAntiAliasingMode::kMono
                                ? FXDIB_Format::k1bppMask
                                : FXDIB_Format::k8bppMask;
if (!pGlyphBitmap->GetBitmap()->Create(dib_width, bitmap.rows, format)) {

For k8bppMask, the allocated buffer is align4(bitmap.width) * bitmap.rows + 4 bytes. However, the MONO expansion loop writes bitmap.width * 3 bytes per row:

// cfx_face.cpp:599-611
if (anti_alias != FontAntiAliasingMode::kMono &&
    bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
  unsigned int bytes = anti_alias == FontAntiAliasingMode::kLcd ? 3 : 1;
  for (unsigned int i = 0; i < bitmap.rows; i++) {
    for (unsigned int n = 0; n < bitmap.width; n++) {
      uint8_t data =
          (pSrcBuf[i * bitmap.pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
      for (unsigned int b = 0; b < bytes; b++) {
        pDestBuf[i * dest_pitch + n * bytes + b] = data;  // overflow
      }
    }
  }
}

When bytes == 3, the write index n * 3 + b reaches bitmap.width * 3 - 1 at the end of each row, but dest_pitch is only align4(bitmap.width). Starting from the second row, every row’s writes begin at an offset that was calculated using the narrow dest_pitch, causing the final rows to write well past the end of the buffer. For a 32-pixel-wide glyph, the total overflow is approximately 60 bytes past the 1028-byte allocation.

Three conditions converge to make this reachable from a crafted PDF:

First, FreeType’s FT_LOAD_NO_BITMAP flag, which PDFium passes when loading glyphs, is explicitly documented as having no effect on bitmap-only fonts: “Ignore bitmap strikes when loading. Bitmap-only fonts ignore this flag.” A bitmap-only TrueType font (one with EBDT/EBLC tables but no glyf outlines, using maxp version 0.5) causes FT_Load_Glyph to return a glyph in FT_GLYPH_FORMAT_BITMAP format with pixel_mode == FT_PIXEL_MODE_MONO.

Second, FT_Render_Glyph silently succeeds when it cannot convert the bitmap format. In FT_Render_Glyph_Internal, after exhausting all renderers and getting FT_Err_Cannot_Render_Glyph, the code explicitly clears the error for bitmap glyphs:

// ftobjs.c:4855-4858
/* it is not an error if we cannot render a bitmap glyph */
if ( FT_ERR_EQ( error, Cannot_Render_Glyph ) &&
     slot->format == FT_GLYPH_FORMAT_BITMAP  )
  error = FT_Err_Ok;

This means FT_Render_Glyph returns success, but the glyph’s pixel_mode remains FT_PIXEL_MODE_MONO, which PDFium does not expect in LCD mode.

Third, Chrome’s PDF viewer defaults to the AGG software renderer because the kPdfUseSkiaRenderer feature flag is FEATURE_DISABLED_BY_DEFAULT in the source code:

// pdf/pdf_features.cc:52
BASE_FEATURE(kPdfUseSkiaRenderer, base::FEATURE_DISABLED_BY_DEFAULT);

Although testing/variations/fieldtrial_testing_config.json enables PdfUseSkiaRenderer on all desktop platforms in Chromium development builds:

// testing/variations/fieldtrial_testing_config.json:19739-19759
"PdfUseSkiaRenderer": [
    {
        "platforms": ["chromeos", "fuchsia", "linux", "mac", "windows"],
        "experiments": [{ "name": "Enabled", "enable_features": ["PdfUseSkiaRenderer"] }]
    }
],

this config is only applied automatically in non-Chrome-branded builds (i.e. Chromium development builds). Chrome-branded release builds require an explicit switch to apply it:

// variations/service/variations_field_trial_creator.cc:135-148
bool ShouldUseFieldTrialTestingConfig(const base::CommandLine* command_line) {
  bool is_enable_switch_set = ...;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  return is_enable_switch_set;  // testing config NOT applied by default
#else
  return is_enable_switch_set ||
         (!command_line->HasSwitch(switches::kDisableFieldTrialTestingConfig) &&
          !command_line->HasSwitch(switches::kVariationsServerURL));
#endif
}

Production Chrome installs that have not received a Finch-pushed Skia enablement therefore use the AGG renderer. The AGG renderer’s DrawDeviceText unconditionally returns false on non-Apple platforms, forcing all text rendering through the software bitmap path (LoadGlyphBitmap to RenderGlyph) where the vulnerability resides. LCD anti-aliasing is selected whenever the display device has 16 or more bits per pixel, which is the common case.

Reproduce

This bug was tested on Chromium commit 89d6357f16ea411b6aa0fc7891b7d9dd18369823 (2026-02-19), which includes PDFium at revision beea56eb350ae1a3d4d0a8c487e179d31e285848. To reproduce, check out that commit with git checkout 89d6357f16ea411b6aa0fc7891b7d9dd18369823 and run gclient sync.

Configure an ASAN build by writing the following to out/asan-release/args.gn:

is_asan = true
is_debug = false
dcheck_always_on = false
target_cpu = "x64"
is_component_build = true

Then build Chrome with autoninja -C out/asan-release chrome.

To trigger the crash, place the attached poc.pdf in the working directory and launch Chrome. The --disable-field-trial-config flag is required because Chromium development builds automatically apply testing/variations/fieldtrial_testing_config.json, which enables PdfUseSkiaRenderer on all desktop platforms; this overrides the code default (FEATURE_DISABLED_BY_DEFAULT) and routes text rendering through Skia, bypassing the vulnerable AGG code path. Disabling the field trial config restores the code default, which uses the AGG renderer, matching the behavior of production Chrome releases where Finch has not enabled Skia for PDF rendering.

ASAN_OPTIONS=detect_odr_violation=0 xvfb-run -a out/asan-release/chrome \
  --no-sandbox --disable-field-trial-config \
  --user-data-dir=/tmp/poc-test poc.pdf

ASAN reports a heap-buffer-overflow WRITE at CFX_Face::RenderGlyph in cfx_face.cpp. The full ASAN log is in asan.log.

=================================================================
==2151182==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7d8f7845f284 at pc 0x7fff881fd09c bp 0x7fffffffb2b0 sp 0x7fffffffb2a8
WRITE of size 1 at 0x7d8f7845f284 thread T0 (chrome)
    #0 0x7fff881fd09b in CFX_Face::RenderGlyph(CFX_Font const*, unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode) third_party/pdfium/core/fxge/cfx_face.cpp:608:54
    #1 0x7fff88213c1e in CFX_GlyphCache::LookUpGlyphBitmap(CFX_Font const*, CFX_Matrix const&, fxcrt::ByteString const&, unsigned int, bool, int, FontAntiAliasingMode) third_party/pdfium/core/fxge/cfx_glyphcache.cpp:128:17
    #2 0x7fff8821366c in CFX_GlyphCache::LoadGlyphBitmap(CFX_Font const*, unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode, CFX_TextRenderOptions*) third_party/pdfium/core/fxge/cfx_glyphcache.cpp:181:12
    #3 0x7fff882085a3 in CFX_Font::LoadGlyphBitmap(unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode, CFX_TextRenderOptions*) const third_party/pdfium/core/fxge/cfx_font.cpp:400:35
    #4 0x7fff882225ac in CFX_RenderDevice::DrawNormalText(pdfium::span<TextCharPos const, 18446744073709551615ul, TextCharPos const*>, CFX_Font*, float, CFX_Matrix const&, unsigned int, CFX_TextRenderOptions const&) third_party/pdfium/core/fxge/cfx_renderdevice.cpp:1183:26
    #5 0x7fff8882d555 in CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice*, pdfium::span<unsigned int const, 18446744073709551615ul, unsigned int const*>, pdfium::span<float const, 18446744073709551615ul, float const*>, CPDF_Font*, float, CFX_Matrix const&, unsigned int, CPDF_RenderOptions const&) third_party/pdfium/core/fpdfapi/render/cpdf_textrenderer.cpp:176:17
    #6 0x7fff8881b097 in CPDF_RenderStatus::ProcessText(CPDF_TextObject*, CFX_Matrix const&, CFX_Path*) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:919:10
    #7 0x7fff8881a2e2 in CPDF_RenderStatus::ProcessObjectNoClip(CPDF_PageObject*, CFX_Matrix const&) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:310:14
    #8 0x7fff8881a90c in CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject*, CFX_Matrix const&, PauseIndicatorIface*) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:281:5
    #9 0x7fff88806c12 in CPDF_ProgressiveRenderer::Continue(PauseIndicatorIface*) third_party/pdfium/core/fpdfapi/render/cpdf_progressiverenderer.cpp:95:29
    #10 0x7fff882ce4e9 in (anonymous namespace)::RenderPageImpl(CPDF_PageRenderContext*, CPDF_Page*, CFX_Matrix const&, FX_RECT const&, int, FPDF_COLORSCHEME_ const*, bool, CPDFSDK_PauseAdapter*) third_party/pdfium/fpdfsdk/cpdfsdk_renderpage.cpp:87:23
    #11 0x7fff882ce840 in CPDFSDK_RenderPageWithContext(CPDF_PageRenderContext*, CPDF_Page*, int, int, int, int, int, int, FPDF_COLORSCHEME_ const*, bool, CPDFSDK_PauseAdapter*) third_party/pdfium/fpdfsdk/cpdfsdk_renderpage.cpp:117:3
    #12 0x7fff883157e8 in FPDF_RenderPageBitmapWithColorScheme_Start third_party/pdfium/fpdfsdk/fpdf_progressive.cpp:83:3
    #13 0x7fff88315a67 in FPDF_RenderPageBitmap_Start third_party/pdfium/fpdfsdk/fpdf_progressive.cpp:126:10
    #14 0x555562907ffe in chrome_pdf::PDFiumEngine::ContinuePaint(unsigned long, SkBitmap&) pdf/pdfium/pdfium_engine.cc:3574:10
    #15 0x555562907052 in chrome_pdf::PDFiumEngine::Paint(gfx::Rect const&, SkBitmap&, std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>>&, std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>>&) pdf/pdfium/pdfium_engine.cc:864:11
    #16 0x55556a59eb20 in chrome_pdf::PdfViewWebPlugin::DoPaint(std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>> const&, std::__Cr::vector<chrome_pdf::PaintReadyRect, std::__Cr::allocator<chrome_pdf::PaintReadyRect>>&, std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>>&) pdf/pdf_view_web_plugin.cc:2424:16
    #17 0x55556a59f7bd in non-virtual thunk to chrome_pdf::PdfViewWebPlugin::OnPaint(std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>> const&, std::__Cr::vector<chrome_pdf::PaintReadyRect, std::__Cr::allocator<chrome_pdf::PaintReadyRect>>&, std::__Cr::vector<gfx::Rect, std::__Cr::allocator<gfx::Rect>>&) pdf/pdf_view_web_plugin.cc:2372:3
    #18 0x5555628e4768 in chrome_pdf::PaintManager::DoPaint() pdf/paint_manager.cc:377:12
    #19 0x5555628e8674 in base::internal::Invoker<...>::RunOnce(base::internal::BindStateBase*) base/functional/bind_internal.h:740:12
    #20 0x7ffff6b60c82 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) base/functional/callback.h:155:12
    #21 0x7ffff6be216e in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) base/task/common/task_annotator.h:112:5
    #22 0x7ffff6be1146 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:346:40
    #23 0x7ffff6a033f1 in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_default.cc:42:55
    #24 0x7ffff6be37e8 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:650:12
    #25 0x7ffff6acb002 in base::RunLoop::Run(base::Location const&) base/run_loop.cc:135:14
    #26 0x7fffec6025e5 in content::RendererMain(content::MainFunctionParams) content/renderer/renderer_main.cc:364:16
    #27 0x7fffeca34c27 in content::RunZygote(content::ContentMainDelegate*) content/app/content_main_runner_impl.cc:664:14
    #28 0x7fffeca35dee in content::RunOtherNamedProcessTypeMain(...) content/app/content_main_runner_impl.cc:771:12
    #29 0x7fffeca3834a in content::ContentMainRunnerImpl::Run() content/app/content_main_runner_impl.cc:1150:10
    #30 0x7fffeca32ad3 in content::RunContentProcess(content::ContentMainParams, content::ContentMainRunner*) content/app/content_main.cc:358:36
    #31 0x7fffeca32e5a in content::ContentMain(content::ContentMainParams) content/app/content_main.cc:371:10
    #32 0x55555bd7ff15 in ChromeMain chrome/app/chrome_main.cc:191:12
    #33 0x7fff86429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

0x7d8f7845f284 is located 0 bytes after 1028-byte region [0x7d8f7845ee80,0x7d8f7845f284)
allocated by thread T0 (chrome) here:
    #0 0x55555bd44f02 in calloc (out/asan-release/chrome+0x67f0f02) (BuildId: 7567412c12a003b9)
    #1 0x7fff882348ed in CFX_DIBitmap::Create(int, int, FXDIB_Format, unsigned char*, unsigned int) third_party/pdfium/core/fxge/dib/cfx_dibitmap.cpp:74:9
    #2 0x7fff881fc910 in CFX_Face::RenderGlyph(CFX_Font const*, unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode) third_party/pdfium/core/fxge/cfx_face.cpp:592:35
    #3 0x7fff88213c1e in CFX_GlyphCache::LookUpGlyphBitmap(CFX_Font const*, CFX_Matrix const&, fxcrt::ByteString const&, unsigned int, bool, int, FontAntiAliasingMode) third_party/pdfium/core/fxge/cfx_glyphcache.cpp:128:17
    #4 0x7fff8821366c in CFX_GlyphCache::LoadGlyphBitmap(CFX_Font const*, unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode, CFX_TextRenderOptions*) third_party/pdfium/core/fxge/cfx_glyphcache.cpp:181:12
    #5 0x7fff882085a3 in CFX_Font::LoadGlyphBitmap(unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode, CFX_TextRenderOptions*) const third_party/pdfium/core/fxge/cfx_font.cpp:400:35
    #6 0x7fff882225ac in CFX_RenderDevice::DrawNormalText(pdfium::span<TextCharPos const, 18446744073709551615ul, TextCharPos const*>, CFX_Font*, float, CFX_Matrix const&, unsigned int, CFX_TextRenderOptions const&) third_party/pdfium/core/fxge/cfx_renderdevice.cpp:1183:26
    #7 0x7fff8882d555 in CPDF_TextRenderer::DrawNormalText(...) third_party/pdfium/core/fpdfapi/render/cpdf_textrenderer.cpp:176:17
    #8 0x7fff8881b097 in CPDF_RenderStatus::ProcessText(CPDF_TextObject*, CFX_Matrix const&, CFX_Path*) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:919:10
    #9 0x7fff8881a2e2 in CPDF_RenderStatus::ProcessObjectNoClip(CPDF_PageObject*, CFX_Matrix const&) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:310:14
    #10 0x7fff8881a90c in CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject*, CFX_Matrix const&, PauseIndicatorIface*) third_party/pdfium/core/fpdfapi/render/cpdf_renderstatus.cpp:281:5
    #11 0x7fff88806c12 in CPDF_ProgressiveRenderer::Continue(PauseIndicatorIface*) third_party/pdfium/core/fpdfapi/render/cpdf_progressiverenderer.cpp:95:29
    #12 0x7fff882ce4e9 in RenderPageImpl(...) third_party/pdfium/fpdfsdk/cpdfsdk_renderpage.cpp:87:23
    #13 0x7fff882ce840 in CPDFSDK_RenderPageWithContext(...) third_party/pdfium/fpdfsdk/cpdfsdk_renderpage.cpp:117:3
    #14 0x7fff883157e8 in FPDF_RenderPageBitmapWithColorScheme_Start third_party/pdfium/fpdfsdk/fpdf_progressive.cpp:83:3
    #15 0x7fff88315a67 in FPDF_RenderPageBitmap_Start third_party/pdfium/fpdfsdk/fpdf_progressive.cpp:126:10
    #16 0x555562907ffe in chrome_pdf::PDFiumEngine::ContinuePaint(unsigned long, SkBitmap&) pdf/pdfium/pdfium_engine.cc:3574:10
    #17 0x555562907052 in chrome_pdf::PDFiumEngine::Paint(...) pdf/pdfium/pdfium_engine.cc:864:11
    ...
    #26 0x7fffec6025e5 in content::RendererMain(content::MainFunctionParams) content/renderer/renderer_main.cc:364:16
    #32 0x55555bd7ff15 in ChromeMain chrome/app/chrome_main.cc:191:12

SUMMARY: AddressSanitizer: heap-buffer-overflow third_party/pdfium/core/fxge/cfx_face.cpp:608:54 in CFX_Face::RenderGlyph(CFX_Font const*, unsigned int, bool, CFX_Matrix const&, int, FontAntiAliasingMode)
==2151182==ABORTING

Credit

Please use c6eed09fc8b174b0f3eebedcceb1e792 as the credit for this vulnerability. Thank you.

View on issue tracker