diff options
author | Surajit Podder <spodder@codeaurora.org> | 2018-01-29 14:23:56 +0530 |
---|---|---|
committer | Vasantha Balla <vballa@codeaurora.org> | 2018-03-14 10:09:38 +0530 |
commit | 9ab537860bf0c6f9ecce0c9d1e37211efaef9afb (patch) | |
tree | 97f09f41140ec6b79f60a259bff8a4627f2883ab | |
parent | fa814875544edf827ca3b4f7287268930ba6dcc7 (diff) | |
download | android_hardware_qcom_media-9ab537860bf0c6f9ecce0c9d1e37211efaef9afb.tar.gz android_hardware_qcom_media-9ab537860bf0c6f9ecce0c9d1e37211efaef9afb.tar.bz2 android_hardware_qcom_media-9ab537860bf0c6f9ecce0c9d1e37211efaef9afb.zip |
mm-video-v4l2: Protect buffer access and increase input buffer size
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.
Change-Id: Ic570d8248806ee492f68b51cb73139cf5c5028e5
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 3 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp | 32 |
2 files changed, 28 insertions, 7 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 810ccb4d..bcc61816 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 - 2017, The Linux Foundation. All rights reserved. +Copyright (c) 2010 - 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 @@ -1289,6 +1289,7 @@ class omx_vdec: public qc_omx_component } }; client_extradata_info m_client_out_extradata_info; + bool m_buffer_error; OMX_ERRORTYPE get_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext); diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp index be77259f..2a3829c7 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2017, The Linux Foundation. All rights reserved. +Copyright (c) 2010 - 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: @@ -675,7 +675,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false), current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL), secure_scaling_to_non_secure_opb(false), m_force_compressed_for_dpb(true), - m_is_display_session(false) + m_is_display_session(false), + m_buffer_error(false) { m_pipe_in = -1; m_pipe_out = -1; @@ -6038,6 +6039,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) { @@ -6547,7 +6549,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) { @@ -6790,6 +6791,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; (void) hComp; (void) port; @@ -6849,8 +6851,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 ? SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED); @@ -7407,6 +7411,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 { @@ -7467,6 +7475,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, (void) hComp; 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"); @@ -7483,7 +7492,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 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"); @@ -7604,6 +7613,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); post_event(OMX_CommandStateSet, OMX_StateLoaded, OMX_COMPONENT_GENERATE_EVENT); + m_buffer_error = false; } } return eRet; @@ -7775,6 +7785,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 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 && @@ -8076,6 +8091,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) { @@ -8084,6 +8100,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*/ @@ -9484,7 +9504,7 @@ int omx_vdec::async_message_process (void *context, void* message) if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) { omx->request_perf_level(VIDC_NOMINAL); } - if (omx->output_use_buffer && omxhdr->pBuffer && + if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer && vdec_msg->msgdata.output_frame.bufferaddr) memcpy ( omxhdr->pBuffer, (void *) ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + |