shithub: openh264

Download patch

ref: 19a94866097ea96da09c9ecdd0a23a9971523f21
parent: 71d619c9f533792db219af254bee3d500aaeeaa5
author: xiaotiansf <xiaotianshimail@gmail.com>
date: Wed Feb 13 07:16:03 EST 2019

Fix ossz-fuzz reported bug-13001.  the fix has added one error code in codec_app_def.h which handles null ptrs in ref pic lists within refCount.

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -78,13 +78,14 @@
   /**
   * Errors derived from bitstream parsing
   */
-  dsErrorFree           = 0x00,   ///< bit stream error-free
-  dsFramePending        = 0x01,   ///< need more throughput to generate a frame output,
-  dsRefLost             = 0x02,   ///< layer lost at reference frame with temporal id 0
-  dsBitstreamError      = 0x04,   ///< error bitstreams(maybe broken internal frame) the decoder cared
-  dsDepLayerLost        = 0x08,   ///< dependented layer is ever lost
-  dsNoParamSets         = 0x10,   ///< no parameter set NALs involved
-  dsDataErrorConcealed  = 0x20,   ///< current data error concealed specified
+  dsErrorFree = 0x00,   ///< bit stream error-free
+  dsFramePending = 0x01,   ///< need more throughput to generate a frame output,
+  dsRefLost = 0x02,   ///< layer lost at reference frame with temporal id 0
+  dsBitstreamError = 0x04,   ///< error bitstreams(maybe broken internal frame) the decoder cared
+  dsDepLayerLost = 0x08,   ///< dependented layer is ever lost
+  dsNoParamSets = 0x10,   ///< no parameter set NALs involved
+  dsDataErrorConcealed = 0x20,   ///< current data error concealed specified
+  dsRefListNullPtrs = 0x40, ///<ref picure list contains null ptrs within uiRefCount range
 
   /**
   * Errors derived from logic level
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -62,9 +62,15 @@
     ++listCount;
   }
   for (int32_t list = LIST_0; list < listCount; ++list) {
-    int32_t refCount = pCtx->sRefPic.uiRefCount[list];
-    for (int32_t refIdx = 0; refIdx < refCount; ++refIdx) {
-      if (!pCtx->sRefPic.pRefList[list][refIdx]) {
+    int32_t shortRefCount = pCtx->sRefPic.uiShortRefCount[list];
+    for (int32_t refIdx = 0; refIdx < shortRefCount; ++refIdx) {
+      if (!pCtx->sRefPic.pShortRefList[list][refIdx]) {
+        return false;
+      }
+    }
+    int32_t longRefCount = pCtx->sRefPic.uiLongRefCount[list];
+    for (int32_t refIdx = 0; refIdx < longRefCount; ++refIdx) {
+      if (!pCtx->sRefPic.pLongRefList[list][refIdx]) {
         return false;
       }
     }
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2720,7 +2720,10 @@
       DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
       pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
       if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
-        MarkECFrameAsRef (pCtx);
+        if (MarkECFrameAsRef (pCtx) == ERR_INFO_INVALID_PTR) {
+          pCtx->iErrorCode |= dsRefListNullPtrs;
+          return false;
+        }
       }
     } else if (pCtx->pParam->bParseOnly) { //clear parse only internal data status
       pCtx->pParserBsInfo->iNalNum = 0;
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -792,6 +792,9 @@
   if (pRefPic->uiShortRefCount[LIST_0] > 0) {
     // Check the duplicate frame_num in short ref list
     for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
+      if (!pRefPic->pShortRefList[LIST_0][iPos]) {
+        return ERR_INFO_INVALID_PTR;
+      }
       if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
         // Replace the previous ref pic with the new one with the same frame_num
         pRefPic->pShortRefList[LIST_0][iPos] = pPic;
@@ -819,6 +822,9 @@
     pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
   } else {
     for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
+      if (!pRefPic->pLongRefList[LIST_0][i]) {
+        return ERR_INFO_INVALID_PTR;
+      }
       if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
         break;
       }
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -593,6 +593,12 @@
       }
       return dsErrorFree;
     }
+    if (m_pDecContext->iErrorCode & dsRefListNullPtrs) {
+      if (ResetDecoder()) {
+        return dsRefListNullPtrs;
+      }
+      return dsErrorFree;
+    }
     //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
     if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
         (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {