diff options
author | Praveen Chavan <pchavan@codeaurora.org> | 2016-04-25 10:03:42 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2016-05-05 08:28:13 -0700 |
commit | 97e3ddfad60bf0417cbbc93dda97d2b887589fc0 (patch) | |
tree | a0a11a2fabcdf1e53c2c4d420b618ccbd1a93215 /msm8974 | |
parent | 0db330f0ede890a2c99a73b5c5e53c41a2c87aa3 (diff) | |
download | media-97e3ddfad60bf0417cbbc93dda97d2b887589fc0.tar.gz |
mm-video-v4l2: vdec: Avoid processing ETBs/FTBs in invalid states
(per the spec) ETB/FTB should not be handled in states other than
Executing, Paused and Idle. This avoids accessing invalid buffers.
Also add a lock to protect the private-buffers from being deleted
while accessing from another thread.
Bug: 27890802
Security Vulnerability - Heap Use-After-Free and Possible LPE in
MediaServer (libOmxVdec problem #6)
Change-Id: Iaac2e383cd53cf9cf8042c9ed93ddc76dba3907e
Diffstat (limited to 'msm8974')
-rwxr-xr-x | msm8974/mm-video-v4l2/vidc/common/inc/vidc_debug.h | 14 | ||||
-rw-r--r-- | msm8974/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 1 | ||||
-rw-r--r-- | msm8974/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 37 |
3 files changed, 38 insertions, 14 deletions
diff --git a/msm8974/mm-video-v4l2/vidc/common/inc/vidc_debug.h b/msm8974/mm-video-v4l2/vidc/common/inc/vidc_debug.h index 0ce747c..d9007f2 100755 --- a/msm8974/mm-video-v4l2/vidc/common/inc/vidc_debug.h +++ b/msm8974/mm-video-v4l2/vidc/common/inc/vidc_debug.h @@ -31,6 +31,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef _ANDROID_ #include <cstdio> +#include <pthread.h> enum { PRIO_ERROR=0x1, @@ -75,4 +76,17 @@ extern int debug_level; } \ } \ +class auto_lock { + public: + auto_lock(pthread_mutex_t &lock) + : mLock(lock) { + pthread_mutex_lock(&mLock); + } + ~auto_lock() { + pthread_mutex_unlock(&mLock); + } + private: + pthread_mutex_t &mLock; +}; + #endif diff --git a/msm8974/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msm8974/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 83274fb..e3f5d8e 100644 --- a/msm8974/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/msm8974/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -783,6 +783,7 @@ class omx_vdec: public qc_omx_component //************************************************************* pthread_mutex_t m_lock; pthread_mutex_t c_lock; + pthread_mutex_t buf_lock; //sem to handle the minimum procesing of commands sem_t m_cmd_lock; sem_t m_safe_flush; diff --git a/msm8974/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/msm8974/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp index 9e1590d..1f898a3 100644 --- a/msm8974/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp +++ b/msm8974/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -691,6 +691,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false), m_vendor_config.pData = NULL; pthread_mutex_init(&m_lock, NULL); pthread_mutex_init(&c_lock, NULL); + pthread_mutex_init(&buf_lock, NULL); sem_init(&m_cmd_lock,0,0); sem_init(&m_safe_flush, 0, 0); streaming[CAPTURE_PORT] = @@ -818,6 +819,7 @@ omx_vdec::~omx_vdec() close(drv_ctx.video_driver_fd); pthread_mutex_destroy(&m_lock); pthread_mutex_destroy(&c_lock); + pthread_mutex_destroy(&buf_lock); sem_destroy(&m_cmd_lock); if (perf_flag) { DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); @@ -5084,6 +5086,9 @@ 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) { DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) { @@ -6042,7 +6047,9 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_ERRORTYPE ret1 = OMX_ErrorNone; unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; - if (m_state == OMX_StateInvalid) { + if (m_state != OMX_StateExecuting && + m_state != OMX_StatePause && + m_state != OMX_StateIdle) { DEBUG_PRINT_ERROR("Empty this buffer in Invalid State"); return OMX_ErrorInvalidState; } @@ -6176,9 +6183,10 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorNone; } + auto_lock l(buf_lock); temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; - if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) { + if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) { return OMX_ErrorBadParameter; } /* If its first frame, H264 codec and reject is true, then parse the nal @@ -6204,7 +6212,7 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, /*for use buffer we need to memcpy the data*/ temp_buffer->buffer_len = buffer->nFilledLen; - if (input_use_buffer) { + if (input_use_buffer && temp_buffer->bufferaddr) { if (buffer->nFilledLen <= temp_buffer->buffer_len) { if (arbitrary_bytes) { memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); @@ -6372,6 +6380,18 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_BUFFERHEADERTYPE* buffer) { + if (m_state != OMX_StateExecuting && + m_state != OMX_StatePause && + m_state != OMX_StateIdle) { + DEBUG_PRINT_ERROR("FTB in Invalid State"); + return OMX_ErrorInvalidState; + } + + if (!m_out_bEnabled) { + DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + unsigned nPortIndex = 0; if (dynamic_buf_mode) { private_handle_t *handle = NULL; @@ -6415,17 +6435,6 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, buffer->nAllocLen = handle->size; } - - if (m_state == OMX_StateInvalid) { - DEBUG_PRINT_ERROR("FTB in Invalid State"); - return OMX_ErrorInvalidState; - } - - if (!m_out_bEnabled) { - DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - nPortIndex = buffer - client_buffers.get_il_buf_hdr(); if (buffer == NULL || (nPortIndex >= drv_ctx.op_buf.actualcount)) { |