CVE-2026-4455
Overview
Background
- `CFX_Face::RenderGlyph()`
- the PDFium routine (named in the commit subject) that asks FreeType to rasterize a glyph and copies the resulting
ft_bitmapinto 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 asrow * dest_pitch + column_offset. - Spanification (`pdfium::span`, `UNSAFE_TODO`)
- PDFium’s migration from raw pointers to bounds-checked spans;
UNSAFE_TODOmarks code that still performs unchecked pointer arithmetic.
Root Cause Analysis
Verify before building a PoC
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.
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
- 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.
- Glyph rasterization
PDFium renders text and calls into the glyph-rendering path, which has FreeType rasterize the glyph and produce
ft_bitmap. - 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_bitmapwas allocated for (inferred; the sizing logic is not in the diff). - Heap overflow
the unchecked loop,
FXSYS_memset, orFXSYS_memcpywrites past the end of the destination bitmap buffer, corrupting adjacent heap memory (what lies there is inferred).
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
forcore/fxge/cfx_face.cpp |
modified |
Files Changed
core/fxge/cfx_face.cpp
Audit Directions
- Remaining `UNSAFE_TODO` source readsthe
pSrcBuf[i * ft_bitmap.pitch + n / 8]read and thepdfium::span(pSrcBuf + row * ft_bitmap.pitch, rowbytes)construction are still unchecked; audit them (including negativeft_bitmap.pitchhandling, given theabs()use) for out-of-bounds reads of FreeType’s buffer. - Producer/consumer geometry mismatcheslook for other places in
core/fxge(and other font backends) that size aCFX_DIBitmapfrom one set of dimensions and then fill it using FreeType-reportedrows/width/pitchor an anti-aliasing byte multiplier. - Raw-pointer pixel loopsgrep PDFium for
GetWritableBuffer().data()andUNSAFE_TODOblocks that performrow * pitch + col * bpparithmetic, and prioritise them for spanification.
Patch
From 1765e514c52f0bbda24041e37fd1c61d09bda831 Mon Sep 17 00:00:00 2001 From: Tom Sepez <[email protected]> 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 <[email protected]> Reviewed-by: Lei Zhang <[email protected]> --- 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; }
Original Bug Report
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.