summaryrefslogtreecommitdiff
path: root/msm8998
diff options
context:
space:
mode:
authorSanthosh Behara <santhoshbehara@codeaurora.org>2017-09-14 16:53:45 +0530
committerMarco Nelissen <marcone@google.com>2017-09-28 08:54:45 -0700
commitcdb855bdd19c9160312195b3a2bfdd72460d281e (patch)
tree9da95f59449fb3e02f458570d3bee2ca1eb3cc71 /msm8998
parent2c15b5832ac2631b27b2ec20936b3161fd167939 (diff)
downloadmedia-cdb855bdd19c9160312195b3a2bfdd72460d281e.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 'msm8998')
-rw-r--r--msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h1
-rw-r--r--msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp19
-rw-r--r--msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp7
3 files changed, 19 insertions, 8 deletions
diff --git a/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 41ad538..b69d284 100644
--- a/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/msm8998/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -699,6 +699,7 @@ class omx_video: public qc_omx_component
bool allocate_native_handle;
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/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index 3e7d489..20eb1ad 100644
--- a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -297,6 +297,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),
@@ -2746,7 +2747,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;
@@ -2897,6 +2897,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);
@@ -2934,6 +2935,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) {
@@ -2942,7 +2945,6 @@ OMX_ERRORTYPE omx_video::use_buffer(
DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
eRet = OMX_ErrorBadPortIndex;
}
-
if (eRet == OMX_ErrorNone) {
if (allocate_done()) {
if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
@@ -3005,7 +3007,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");
@@ -3549,7 +3550,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_
@@ -3620,7 +3621,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");
@@ -3697,7 +3703,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;
@@ -3977,7 +3982,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/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index 9974467..33410a9 100644
--- a/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/msm8998/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -2308,11 +2308,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]);
}
@@ -2677,7 +2681,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),