summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanthosh Behara <santhoshbehara@codeaurora.org>2018-05-15 06:09:50 -0700
committerKevin F. Haggerty <haggertk@lineageos.org>2018-09-05 20:45:55 -0600
commit330d8527207b063e7b865896b846470e55e82c84 (patch)
tree27e95f496618a0c7eee9bb9682085869f2c85de1
parent29e06f3f904645c899a3a2601014fd913ba22e94 (diff)
downloadandroid_hardware_qcom_media-lineage-15.1-caf-8084.tar.gz
android_hardware_qcom_media-lineage-15.1-caf-8084.tar.bz2
android_hardware_qcom_media-lineage-15.1-caf-8084.zip
mm-video-v4l2: Protect buffer access and increase input buffer sizelineage-15.1-caf-8084
Protect buffer access for below scenarios: *Increase the scope of buf_lock in free_buffer to avoid access of freed buffer for both input and output buffers. Also, add check before output buffer access. *Disallow allocate buffer mode after client has called use buffer. Allocate additional 512 bytes of memory for input buffers on top of allocation size as per hardware requirement. Bug: 64340487 Test: ran POC on bullhead/nyc-dev Change-Id: Iabbb2d7e00ff97bfc47b04386feec66976fca99a (cherry picked from commit 83aeab22d1bdc493b3ea2f50616bb8fd460d6c74)
-rw-r--r--mm-video-v4l2/vidc/vdec/inc/omx_vdec.h3
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp33
2 files changed, 28 insertions, 8 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 9b01376d..07cbcc77 100644
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2010 - 2014, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -1066,6 +1066,7 @@ class omx_vdec: public qc_omx_component
}
static OMX_ERRORTYPE describeColorFormat(OMX_PTR params);
+ bool m_buffer_error;
};
#ifdef _MSM8974_
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
index 885f5155..d9429c5e 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2010 - 2014, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -575,7 +575,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
m_profile(0),
client_set_fps(false),
m_last_rendered_TS(-1),
- m_queued_codec_config_count(0)
+ m_queued_codec_config_count(0),
+ m_buffer_error(false)
{
/* Assumption is that , to begin with , we have all the frames with decoder */
DEBUG_PRINT_HIGH("In OMX vdec Constructor");
@@ -4491,6 +4492,7 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer(
eRet = allocate_output_headers();
if (eRet == OMX_ErrorNone)
eRet = allocate_extradata();
+ output_use_buffer = true;
}
if (eRet == OMX_ErrorNone) {
@@ -4893,7 +4895,6 @@ OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
index = bufferHdr - m_inp_mem_ptr;
DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
- auto_lock l(buf_lock);
bufferHdr->pInputPortPrivate = NULL;
if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
@@ -5103,6 +5104,7 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
unsigned i = 0;
unsigned char *buf_addr = NULL;
int pmem_fd = -1;
+ unsigned int align_size = 0;
if (bytes != drv_ctx.ip_buf.buffer_size) {
DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
@@ -5158,8 +5160,10 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
int rc;
DEBUG_PRINT_LOW("Allocate input Buffer");
#ifdef USE_ION
+ align_size = drv_ctx.ip_buf.buffer_size + 512;
+ align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
- drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
+ align_size, drv_ctx.op_buf.alignment,
&drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
&drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
@@ -5640,6 +5644,10 @@ OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hC
eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
}
} else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
+ if (output_use_buffer) {
+ DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
+ return OMX_ErrorBadParameter;
+ }
eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
appData,bytes);
} else {
@@ -5699,6 +5707,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp __unuse
unsigned int nPortIndex;
DEBUG_PRINT_LOW("In for decoder free_buffer");
+ auto_lock l(buf_lock);
if (m_state == OMX_StateIdle &&
(BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
@@ -5715,7 +5724,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp __unuse
post_event(OMX_EventError,
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
-
+ m_buffer_error = true;
return OMX_ErrorIncorrectStateOperation;
} else if (m_state != OMX_StateInvalid) {
DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
@@ -5723,7 +5732,6 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp __unuse
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
}
-
if (port == OMX_CORE_INPUT_PORT_INDEX) {
/*Check if arbitrary bytes*/
if (!arbitrary_bytes && !input_use_buffer)
@@ -5820,6 +5828,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp __unuse
BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
post_event(OMX_CommandStateSet, OMX_StateLoaded,
OMX_COMPONENT_GENERATE_EVENT);
+ m_buffer_error = false;
}
}
return eRet;
@@ -5983,6 +5992,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE h
if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
return OMX_ErrorBadParameter;
}
+
+ if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
+ DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
/* If its first frame, H264 codec and reject is true, then parse the nal
and get the profile. Based on this, reject the clip playback */
if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
@@ -6280,6 +6294,7 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
struct vdec_bufferpayload *ptr_outputbuffer = NULL;
struct vdec_output_frameinfo *ptr_respbuffer = NULL;
+ auto_lock l(buf_lock);
nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
@@ -6288,6 +6303,10 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
return OMX_ErrorBadParameter;
}
+ if (BITMASK_ABSENT(&m_out_bm_count, nPortIndex) || m_buffer_error) {
+ DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
bufferAdd, bufferAdd->pBuffer);
/*Return back the output buffer to client*/
@@ -7437,7 +7456,7 @@ int omx_vdec::async_message_process (void *context, void* message)
output_respbuf->pic_type = PICTURE_TYPE_B;
}
- if (omx->output_use_buffer)
+ if (!omx->m_enable_android_native_buffers && omx->output_use_buffer)
memcpy ( omxhdr->pBuffer, (void *)
((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
(unsigned long)vdec_msg->msgdata.output_frame.offset),