Pdfium - Out-of-Bounds Read with Shading Pattern Backed by Pattern Colorspace

EDB-ID: 44083
Author: Google Security Research
Published: 2018-02-15
Type: Dos
Platform: Multiple
Aliases: N/A
Advisory/Source: Link
Tags: Out Of Bounds
Vulnerable App: N/A

When parsing ShadingPatterns; according to the specification they shouldn't be permitted to have a pattern colorspace as their base colorspace, but this is not validated, leading to out-of-bounds reads when rendering using the malformed shading pattern.

bool CPDF_ShadingPattern::Load() {

// ... snip ...

CPDF_Object* pCSObj = pShadingDict->GetDirectObjectFor("ColorSpace");
if (!pCSObj)
return false;

// No validation here on the type of colorspace.

// ... snip ...

return true;

If we now look at the code called during rendering of this pattern, we call through DrawFreeGouraudShading (cpdf_renderstatus.cpp), which will call CPDF_MeshStream::ReadVertex for each vertex in the shading pattern, which will call CPDF_MeshStream::ReadColor.

std::tuple<float, float, float> CPDF_MeshStream::ReadColor() {

float color_value[kMaxComponents];
for (uint32_t i = 0; i < m_nComponents; ++i) {
color_value[i] = m_ColorMin[i] + m_BitStream->GetBits(m_nComponentBits) *
(m_ColorMax[i] - m_ColorMin[i]) /

// NB: color_value has only been initialised for the first m_nComponents elements

float r = 0.0;
float g = 0.0;
float b = 0.0;
if (m_funcs.empty()) {
m_pCS->GetRGB(color_value, &r, &g, &b); // <-- we're interested in this call here
return std::tuple<float, float, float>(r, g, b);

// ... snip ...

This call to GetRGB will be into the pattern cs

bool CPDF_PatternCS::GetRGB(float* pBuf, float* R, float* G, float* B) const {
if (m_pBaseCS) {
ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
PatternValue* pvalue = (PatternValue*)pBuf;
// pvalue->m_Comps is now pointing 5 dwords into an 8 dword sized buffer, and p_pBaseCS expects to be able to read 8 dwords from it.
if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B))
return true;
*R = 0.75f;
*G = 0.75f;
*B = 0.75f;
return false;

Originally reported without 90 day deadline as https://bugs.chromium.org/p/chromium/issues/detail?id=795251, since it wasn't clear that there was an easy way to use the oob-read to leak information in a way that was useful, deadline applied as of 15/12 after working out how to use this as an information leak for issue 1489 .

Proof of Concept:

Related Posts