[ authorization ] [ registration ] [ restore account ]
Contact us
You can contact us by:
0day Today Exploits Market and 0day Exploits Database

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

Author
Google Security Research
Risk
[
Security Risk Medium
]
0day-ID
0day-ID-29798
Category
dos / poc
Date add
15-02-2018
Platform
multiple
Related to  issue 1490 .
 
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() {
  ASSERT(ShouldCheckBPC(m_type));
 
  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]) /
                                         m_ComponentMax;
  }
 
  // 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:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/44083.zip

#  0day.today [2024-12-23]  #