From 7dc63e6c53add27084929ffe52436b7bb6667a80 Mon Sep 17 00:00:00 2001 From: JUN FANG Date: Sat, 31 Jan 2015 10:12:50 -0800 Subject: Fix heap buffer overflow in CPDF_SampledFunc::v_Call This issue was caused by integer overflow in CPDF_SampledFunc::v_Call. The root cause of this issue is that the content in the test pdf file was damaged. The solution is to check whether an integer is overflow before using it. BUG=452455 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/886953002 --- core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp index 649bd54a33..3ceb0f7e8b 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp @@ -6,6 +6,7 @@ #include "../../../include/fpdfapi/fpdf_page.h" #include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../third_party/numerics/safe_conversions_impl.h" #include "pageint.h" #include class CPDF_PSEngine; @@ -553,13 +554,24 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const } pos += index[i] * blocksize[i]; } - int bitpos = pos * m_nBitsPerSample * m_nOutputs; + FX_SAFE_INT32 bitpos = pos; + bitpos *= m_nBitsPerSample; + bitpos *= m_nOutputs; + if (!bitpos.IsValid()) { + return FALSE; + } FX_LPCBYTE pSampleData = m_pSampleStream->GetData(); if (pSampleData == NULL) { return FALSE; } + FX_SAFE_INT32 bitpos1 = m_nOutputs - 1 > 0 ? m_nOutputs - 1 : 0; + bitpos1 *= m_nBitsPerSample; + bitpos1 += bitpos.ValueOrDie(); + if (!bitpos1.IsValid()) { + return FALSE; + } for (int j = 0; j < m_nOutputs; j ++) { - FX_DWORD sample = _GetBits32(pSampleData, bitpos + j * m_nBitsPerSample, m_nBitsPerSample); + FX_DWORD sample = _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, m_nBitsPerSample); FX_FLOAT encoded = (FX_FLOAT)sample; for (int i = 0; i < m_nInputs; i ++) { if (index[i] == m_pEncodeInfo[i].sizes - 1) { @@ -567,8 +579,15 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const encoded = encoded_input[i] * (FX_FLOAT)sample; } } else { - int bitpos1 = bitpos + m_nBitsPerSample * m_nOutputs * blocksize[i]; - FX_DWORD sample1 = _GetBits32(pSampleData, bitpos1 + j * m_nBitsPerSample, m_nBitsPerSample); + FX_SAFE_INT32 bitpos2 = blocksize[i]; + bitpos2 += 1; + bitpos2 *= m_nBitsPerSample; + bitpos2 *= m_nOutputs; + bitpos2 += bitpos.ValueOrDie(); + if (!bitpos2.IsValid()) { + return FALSE; + } + FX_DWORD sample1 = _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); encoded += (encoded_input[i] - index[i]) * ((FX_FLOAT)sample1 - (FX_FLOAT)sample); } } -- cgit v1.2.3