History

Merge pull request #2657 from huili2/parseonly_length_overflow_crashfix_final

fix parseonly length overflow

ruil2 committed 9 years ago

Commit 74c02a52 parents b84f056 17139518 files · +370 −24Browse files

Showing the changes to codec/decoder/core/src/decoder_core.cpp (1 of 8 files). Show all

Unified · Split

codec/decoder/core/src/decoder_core.cpp+59−5
@@ -81,7 +81,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 80 unmodified lines
8181 int32_t iNalLen = 0;
8282 int32_t iNum = 0;
8383 while (iNum < pParser->iNalNum) {
84− iTotalNalLen += pParser->iNalLenInByte[iNum++];
84+ iTotalNalLen += pParser->pNalLenInByte[iNum++];
8585 }
8686 uint8_t* pDstBuf = pParser->pDstBuff + iTotalNalLen;
8787 int32_t iIdx = pCurAu->uiStartPos;
@@ -96,6 +96,12 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 8 unmodified lines
9696
9797 if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR
9898 if (pCtx->bFrameFinish) { //add required sps/pps
99+ if (pParser->iNalNum > pCtx->iMaxNalNum - 2) { //2 reserved for sps+pps
100+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
101+ "DecodeFrameConstruction(): current NAL num (%d) plus sps & pps exceeds permitted num (%d). Will expand",
102+ pParser->iNalNum, pCtx->iMaxNalNum);
103+ WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + 2))
104+ }
99105 bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType);
100106 SSpsBsInfo* pSpsBs = NULL;
101107 SPpsBsInfo* pPpsBs = NULL;
@@ -114,21 +120,26 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 12 unmodified lines
114120 return ERR_INFO_OUT_OF_MEMORY;
115121 }
116122 memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen);
117− pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen;
118− pCtx->iNalLenInByte[pCtx->iNalNum ++] = pSpsBs->uiSpsBsLen;
123+ pParser->pNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen;
119124 pDstBuf += pSpsBs->uiSpsBsLen;
120125 memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen);
121− pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen;
126+ pParser->pNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen;
122127 pDstBuf += pPpsBs->uiPpsBsLen;
123128 pCtx->bFrameFinish = false;
124129 }
125130 }
126131 //then VCL data re-write
132+ if (pParser->iNalNum + iEndIdx - iIdx + 1 > pCtx->iMaxNalNum) { //calculate total NAL num
133+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
134+ "DecodeFrameConstruction(): current NAL num (%d) exceeds permitted num (%d). Will expand",
135+ pParser->iNalNum + iEndIdx - iIdx + 1, pCtx->iMaxNalNum);
136+ WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + iEndIdx - iIdx + 1))
137+ }
127138 while (iIdx <= iEndIdx) {
128139 pCurNal = pCurAu->pNalUnitsList [iIdx ++];
129140 iNalLen = pCurNal->sNalData.sVclNal.iNalLength;
130141 pNalBs = pCurNal->sNalData.sVclNal.pNalPos;
131− pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen;
142+ pParser->pNalLenInByte [pParser->iNalNum ++] = iNalLen;
132143 if (pDstBuf - pParser->pDstBuff + iNalLen >= MAX_ACCESS_UNIT_CAPACITY) {
133144 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
134145 "DecodeFrameConstruction(): composed output size (%ld) exceeds (%d). Failed to parse. current data pos %d out of %d:, previously accumulated num: %d, total num: %d, previously accumulated len: %d, current len: %d, current buf pos: %p, header buf pos: %p \n",
@@ -504,6 +515,13 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) { · 369 unmodified lines
504515 }
505516 pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead;
506517 pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte;
518+
519+ pCtx->iMaxNalNum = MAX_NAL_UNITS_IN_LAYER + 2; //2 reserved for SPS+PPS
520+ pCtx->pParserBsInfo->pNalLenInByte = static_cast<int*> (pMa->WelsMallocz (pCtx->iMaxNalNum * sizeof (int),
521+ "pCtx->pParserBsInfo->pNalLenInByte"));
522+ if (pCtx->pParserBsInfo->pNalLenInByte == NULL) {
523+ return ERR_INFO_OUT_OF_MEMORY;
524+ }
507525 }
508526 return ERR_NONE;
509527 }
@@ -562,6 +580,37 @@ int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) { · 52 unmodified lines
562580 return ERR_NONE;
563581 }
564582
583+int32_t ExpandBsLenBuffer (PWelsDecoderContext pCtx, const int kiCurrLen) {
584+ SParserBsInfo* pParser = pCtx->pParserBsInfo;
585+ if (!pParser->pNalLenInByte)
586+ return ERR_INFO_INVALID_ACCESS;
587+
588+ int iNewLen = kiCurrLen;
589+ if (kiCurrLen >= MAX_MB_SIZE + 2) { //exceeds the max MB number of level 5.2
590+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Current nal num (%d) exceededs %d.", kiCurrLen, MAX_MB_SIZE);
591+ pCtx->iErrorCode |= dsOutOfMemory;
592+ return ERR_INFO_OUT_OF_MEMORY;
593+ } else {
594+ iNewLen = kiCurrLen << 1;
595+ iNewLen = WELS_MIN (iNewLen, MAX_MB_SIZE + 2);
596+ }
597+
598+ CMemoryAlign* pMa = pCtx->pMemAlign;
599+ int* pNewLenBuffer = static_cast<int*> (pMa->WelsMallocz (iNewLen * sizeof (int),
600+ "pCtx->pParserBsInfo->pNalLenInByte"));
601+ if (pNewLenBuffer == NULL) {
602+ pCtx->iErrorCode |= dsOutOfMemory;
603+ return ERR_INFO_OUT_OF_MEMORY;
604+ }
605+
606+ //copy existing data from old length buffer to new
607+ memcpy (pNewLenBuffer, pParser->pNalLenInByte, pCtx->iMaxNalNum * sizeof (int));
608+ pMa->WelsFree (pParser->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
609+ pParser->pNalLenInByte = pNewLenBuffer;
610+ pCtx->iMaxNalNum = iNewLen;
611+ return ERR_NONE;
612+}
613+
565614 int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) {
566615 if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data
567616 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d",
@@ -633,6 +682,11 @@ void WelsFreeStaticMemory (PWelsDecoderContext pCtx) { · 65 unmodified lines
633682 pCtx->sSavedData.pStartPos = NULL;
634683 pCtx->sSavedData.pCurPos = NULL;
635684 if (pCtx->pParserBsInfo) {
685+ if (pCtx->pParserBsInfo->pNalLenInByte) {
686+ pMa->WelsFree (pCtx->pParserBsInfo->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
687+ pCtx->pParserBsInfo->pNalLenInByte = NULL;
688+ pCtx->iMaxNalNum = 0;
689+ }
636690 if (pCtx->pParserBsInfo->pDstBuff) {
637691 pMa->WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff");
638692 pCtx->pParserBsInfo->pDstBuff = NULL;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t