From 6e5239c6e3891d78e7b9e8262c23cd129f0cdbb7 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Thu, 13 Oct 2016 07:54:09 -0700 Subject: Verify number of ex flags matches number of ex items. Currently the JBig2 decoder can leak subimages in the case where we mark more items in EXFLAGS then we have SDNUMEXSYMS. This Cl checks for this condition and fails the decode if it happens. BUG=chromium:654365 Review-Url: https://codereview.chromium.org/2419553002 --- core/fxcodec/jbig2/JBig2_SddProc.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/fxcodec/jbig2/JBig2_SddProc.cpp b/core/fxcodec/jbig2/JBig2_SddProc.cpp index 1a7e96d26b..f6afb13497 100644 --- a/core/fxcodec/jbig2/JBig2_SddProc.cpp +++ b/core/fxcodec/jbig2/JBig2_SddProc.cpp @@ -38,6 +38,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( uint32_t SBNUMSYMS; uint8_t SBSYMCODELEN; int32_t RDXI, RDYI; + uint32_t num_ex_syms; CJBig2_Image** SBSYMS; std::unique_ptr IAID; std::unique_ptr pDict; @@ -235,6 +236,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( EXINDEX = 0; CUREXFLAG = 0; EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); + num_ex_syms = 0; while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH); if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) { @@ -243,12 +245,19 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( } if (EXRUNLENGTH != 0) { for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { + if (CUREXFLAG) + num_ex_syms++; EXFLAGS[I] = CUREXFLAG; } } EXINDEX = EXINDEX + EXRUNLENGTH; CUREXFLAG = !CUREXFLAG; } + if (num_ex_syms > SDNUMEXSYMS) { + FX_Free(EXFLAGS); + goto failed; + } + pDict.reset(new CJBig2_SymbolDict); I = J = 0; for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { @@ -303,6 +312,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( int32_t RDXI, RDYI; uint32_t BMSIZE; uint32_t stride; + uint32_t num_ex_syms; CJBig2_Image** SBSYMS; std::unique_ptr pHuffmanDecoder( new CJBig2_HuffmanDecoder(pStream)); @@ -555,6 +565,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( pTable.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, HuffmanTable_B1_Size, HuffmanTable_HTOOB_B1)); EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); + num_ex_syms = 0; while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { if (pHuffmanDecoder->decodeAValue(pTable.get(), (int*)&EXRUNLENGTH) != 0) { FX_Free(EXFLAGS); @@ -566,12 +577,20 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( } if (EXRUNLENGTH != 0) { for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { + if (CUREXFLAG) + num_ex_syms++; + EXFLAGS[I] = CUREXFLAG; } } EXINDEX = EXINDEX + EXRUNLENGTH; CUREXFLAG = !CUREXFLAG; } + if (num_ex_syms > SDNUMEXSYMS) { + FX_Free(EXFLAGS); + goto failed; + } + I = J = 0; for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { if (EXFLAGS[I] && J < SDNUMEXSYMS) { -- cgit v1.2.3