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;