Merge tag 'android-security-11.0.0_r54' into int/11/fp3

Android security 11.0.0 release 54

* tag 'android-security-11.0.0_r54':
  Move slice increments after completing header parsing

Change-Id: I734101efcefc81566f290d2a2b132256bf4a286f
diff --git a/decoder/ih264d_bitstrm.h b/decoder/ih264d_bitstrm.h
index 49cd5e7..8bb06fb 100644
--- a/decoder/ih264d_bitstrm.h
+++ b/decoder/ih264d_bitstrm.h
@@ -57,7 +57,7 @@
 {
     UWORD32 u4_ofst; /* Offset in the buffer for the current bit */
     UWORD32 *pu4_buffer; /* Bitstream Buffer  */
-    UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */
+    UWORD32 u4_max_ofst; /* points to first bit beyond the buffer */
     void * pv_codec_handle; /* For Error Handling */
 } dec_bit_stream_t;
 
@@ -88,10 +88,13 @@
  **************************************************************************
  */
 
-#define MORE_RBSP_DATA(ps_bitstrm) \
-  (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst)
+
 #define EXCEED_OFFSET(ps_bitstrm) \
   (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
+#define CHECK_BITS_SUFFICIENT(ps_bitstrm, bits_to_read) \
+  (ps_bitstrm->u4_ofst + bits_to_read <= ps_bitstrm->u4_max_ofst)
+#define MORE_RBSP_DATA(ps_bitstrm) \
+    CHECK_BITS_SUFFICIENT(ps_bitstrm, 1)
 
 void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm);
 UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm);
diff --git a/decoder/ih264d_cabac.c b/decoder/ih264d_cabac.c
index 38028ae..ef1fafc 100644
--- a/decoder/ih264d_cabac.c
+++ b/decoder/ih264d_cabac.c
@@ -69,7 +69,7 @@
              32);
     FLUSHBITS(ps_bitstrm->u4_ofst, 9)
 
-    if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
+    if(EXCEED_OFFSET(ps_bitstrm))
         return ERROR_EOB_FLUSHBITS_T;
 
     ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst;
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index f286e29..9220707 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -463,7 +463,7 @@
 
     /* In case bitstream read has exceeded the filled size, then
        return an error */
-    if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst + 8)
+    if(EXCEED_OFFSET(ps_bitstrm))
     {
         return ERROR_INV_SPS_PPS_T;
     }
@@ -1093,7 +1093,7 @@
 
     /* In case bitstream read has exceeded the filled size, then
      return an error */
-    if (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
+    if (EXCEED_OFFSET(ps_bitstrm))
     {
         return ERROR_INV_SPS_PPS_T;
     }
diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c
index 4375671..ac4d056 100644
--- a/decoder/ih264d_sei.c
+++ b/decoder/ih264d_sei.c
@@ -759,8 +759,12 @@
     {
         ui4_payload_type = 0;
 
+        if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
+        {
+            return ERROR_EOB_GETBITS_T;
+        }
         u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
-        while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm))
+        while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
         {
             u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
             ui4_payload_type += 255;
@@ -768,14 +772,22 @@
         ui4_payload_type += u4_bits;
 
         ui4_payload_size = 0;
+        if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
+        {
+            return ERROR_EOB_GETBITS_T;
+        }
         u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
-        while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm))
+        while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
         {
             u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
             ui4_payload_size += 255;
         }
         ui4_payload_size += u4_bits;
 
+        if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, (ui4_payload_size << 3)))
+        {
+            return ERROR_EOB_GETBITS_T;
+        }
         i4_status = ih264d_parse_sei_payload(ps_bitstrm, ui4_payload_type,
                                              ui4_payload_size, ps_dec);
         if(i4_status != OK)
@@ -789,7 +801,7 @@
                 H264_DEC_DEBUG_PRINT("\nError in parsing SEI message");
             }
             while(0 == ih264d_check_byte_aligned(ps_bitstrm)
-                            && !EXCEED_OFFSET(ps_bitstrm))
+                            && CHECK_BITS_SUFFICIENT(ps_bitstrm, 1))
             {
                 u4_bits = ih264d_get_bit_h264(ps_bitstrm);
                 if(u4_bits)
@@ -799,7 +811,7 @@
             }
         }
     }
-    while(ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst);
+    while(MORE_RBSP_DATA(ps_bitstrm));
     return (i4_status);
 }
 
diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c
index 61ef6b5..53067e0 100644
--- a/encoder/ih264e_api.c
+++ b/encoder/ih264e_api.c
@@ -142,6 +142,101 @@
 *******************************************************************************
 *
 * @brief
+*  Used to test validity of input dimensions
+*
+* @par Description:
+*  Dimensions of the input buffer passed to encode call are validated
+*
+* @param[in] ps_codec
+*  Codec context
+*
+* @param[in] ps_ip
+*  Pointer to input structure
+*
+* @param[out] ps_op
+*  Pointer to output structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec,
+                                              ih264e_video_encode_ip_t *ps_ip,
+                                              ih264e_video_encode_op_t *ps_op)
+{
+    UWORD32 u4_wd, u4_ht;
+    cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
+    iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf;
+
+    u4_wd = ps_inp_buf->au4_wd[0];
+    u4_ht = ps_inp_buf->au4_ht[0];
+    switch (ps_inp_buf->e_color_fmt)
+    {
+        case IV_YUV_420P:
+            if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) ||
+                            ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) ||
+                            (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2]))
+            {
+                ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+                ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+                return (IV_FAIL);
+            }
+            if (((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) ||
+                            ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) ||
+                            (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2]))
+            {
+                ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+                ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+                return (IV_FAIL);
+            }
+            break;
+        case IV_YUV_420SP_UV:
+        case IV_YUV_420SP_VU:
+            if ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1])
+            {
+                ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+                ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+                return (IV_FAIL);
+            }
+            if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1])
+            {
+                ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+                ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+                return (IV_FAIL);
+            }
+            break;
+        case IV_YUV_422ILE:
+            u4_wd = ps_inp_buf->au4_wd[0] / 2;
+            break;
+        default:
+            ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+            ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
+            return (IV_FAIL);
+    }
+
+    if (u4_wd != ps_curr_cfg->u4_disp_wd)
+    {
+        ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+        ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+        return (IV_FAIL);
+    }
+
+    if (u4_ht != ps_curr_cfg->u4_disp_ht)
+    {
+        ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+        ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+        return (IV_FAIL);
+    }
+
+    return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
 *  Used to test arguments for corresponding API call
 *
 * @par Description:
@@ -818,6 +913,7 @@
 
         case IVE_CMD_VIDEO_ENCODE:
         {
+            codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle);
             ih264e_video_encode_ip_t *ps_ip = pv_api_ip;
             ih264e_video_encode_op_t *ps_op = pv_api_op;
 
@@ -836,6 +932,15 @@
                                 IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
                 return (IV_FAIL);
             }
+
+            if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] &&
+                            ps_codec->i4_header_mode != 1 &&
+                            IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op))
+            {
+                ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+                ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
+                return (IV_FAIL);
+            }
             break;
         }
 
@@ -4059,6 +4164,11 @@
     /* Update config params as per input */
     ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
     ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
+
+    /* Initialize dimensions to max dimensions during init */
+    ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd;
+    ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_ht;
+
     ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
     ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
     ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;