summaryrefslogtreecommitdiff
path: root/msm8996
diff options
context:
space:
mode:
authorSanthosh Behara <santhoshbehara@codeaurora.org>2017-09-15 05:28:04 -0700
committerMarco Nelissen <marcone@google.com>2017-10-10 19:21:51 +0000
commitb701fb182bdb32dbafc72406cc27480e12925d71 (patch)
tree0829023d14f9781cb23d3dbe33428b240b0006d9 /msm8996
parenta5698533111c13936e65581ba15c32725e47ebfc (diff)
downloadmedia-b701fb182bdb32dbafc72406cc27480e12925d71.tar.gz
mm-video-v4l2: venc: Avoid buffer access after free
client expects buffer to be free if free_buffer is called, but if omx is in executing state free buffer call will error out. When async thread tries to copy data to client buffer which is already freed,it leads to crash. Added a bitmask to avoid copy to buffer after free. Bug: 36130225 CRs-Fixed: 2106434 Author: Uma Mehta <umamehta@codeaurora.org> Change-Id: Id439aac54ee64a65ea68b6431a9f5150255a6980
Diffstat (limited to 'msm8996')
-rw-r--r--msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h1
-rw-r--r--msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp18
-rw-r--r--msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp7
3 files changed, 19 insertions, 7 deletions
diff --git a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 1a537e4..8fc78ce 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -659,6 +659,7 @@ class omx_video: public qc_omx_component
int pending_output_buffers;
uint64_t m_out_bm_count;
+ uint64_t m_client_out_bm_count;
uint64_t m_inp_bm_count;
uint64_t m_flags;
uint64_t m_etb_count;
diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index fa6b08f..abbcea3 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -295,6 +295,7 @@ omx_video::omx_video():
pending_input_buffers(0),
pending_output_buffers(0),
m_out_bm_count(0),
+ m_client_out_bm_count(0),
m_inp_bm_count(0),
m_flags(0),
m_etb_count(0),
@@ -2598,7 +2599,6 @@ OMX_ERRORTYPE omx_video::use_output_buffer(
return OMX_ErrorBadParameter;
}
- auto_lock l(m_buf_lock);
if (!m_out_mem_ptr) {
output_use_buffer = true;
int nBufHdrSize = 0;
@@ -2749,6 +2749,7 @@ OMX_ERRORTYPE omx_video::use_output_buffer(
}
BITMASK_SET(&m_out_bm_count,i);
+ BITMASK_SET(&m_client_out_bm_count,i);
} else {
DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
"index = %u", i);
@@ -2786,6 +2787,8 @@ OMX_ERRORTYPE omx_video::use_buffer(
DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
return OMX_ErrorInvalidState;
}
+
+ auto_lock l(m_buf_lock);
if (port == PORT_INDEX_IN) {
eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
} else if (port == PORT_INDEX_OUT) {
@@ -2857,7 +2860,6 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
}
if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
- auto_lock l(m_lock);
if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
@@ -3369,7 +3371,7 @@ OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE h
DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
return OMX_ErrorInvalidState;
}
-
+ auto_lock l(m_buf_lock);
// What if the client calls again.
if (port == PORT_INDEX_IN) {
#ifdef _ANDROID_ICS_
@@ -3440,7 +3442,12 @@ OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
unsigned int nPortIndex;
DEBUG_PRINT_LOW("In for encoder free_buffer");
-
+ auto_lock l(m_buf_lock);
+ if (port == PORT_INDEX_OUT) { //client called freebuffer, clearing client buffer bitmask right away to avoid use after free
+ nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
+ if(BITMASK_PRESENT(&m_client_out_bm_count, nPortIndex))
+ BITMASK_CLEAR(&m_client_out_bm_count,nPortIndex);
+ }
if (m_state == OMX_StateIdle &&
(BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
@@ -3517,7 +3524,6 @@ OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
- auto_lock l(m_buf_lock);
// Clear the bit associated with it.
BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
m_sOutPortDef.bPopulated = OMX_FALSE;
@@ -3778,7 +3784,7 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
{
DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
- auto_lock l(m_lock);
+ auto_lock l(m_buf_lock);
pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
if (pmem_data_buf) {
memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index b09400a..1d7c8ba 100644
--- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -2098,11 +2098,15 @@ OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
m_state);
}
+
+ auto_lock l(m_buf_lock);
if (m_out_mem_ptr) {
DEBUG_PRINT_LOW("Freeing the Output Memory");
for (i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) {
if (BITMASK_PRESENT(&m_out_bm_count, i)) {
BITMASK_CLEAR(&m_out_bm_count, i);
+ if (BITMASK_PRESENT(&m_client_out_bm_count, i))
+ BITMASK_CLEAR(&m_client_out_bm_count, i);
free_output_buffer (&m_out_mem_ptr[i]);
}
@@ -2449,7 +2453,8 @@ int omx_venc::async_message_process (void *context, void* message)
omxhdr->nFlags = m_sVenc_msg->buf.flags;
/*Use buffer case*/
- if (omx->output_use_buffer && !omx->m_use_output_pmem && !omx->is_secure_session()) {
+ if (BITMASK_PRESENT(&(omx->m_client_out_bm_count), bufIndex) &&
+ omx->output_use_buffer && !omx->m_use_output_pmem && !omx->is_secure_session()) {
DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
memcpy(omxhdr->pBuffer,
(m_sVenc_msg->buf.ptrbuffer),