From 322c518689a7f820165ca4c5d6b750b02ac34665 Mon Sep 17 00:00:00 2001 From: Jim Rasche Date: Mon, 22 Jul 2013 15:03:50 -0700 Subject: msm:camera: Fix multiple bounds check Added bounds check to user input num_streams at several location, without checking a position outside array could be dereferenced Change-Id: I6e82d8b51e4ec6772316c7daef243240c029db96 Signed-off-by: Jim Rasche --- .../platform/msm/camera_v2/isp/msm_isp_axi_util.c | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 5b7658d..746425b 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -300,7 +300,16 @@ int msm_isp_axi_check_stream_state( struct msm_vfe_axi_stream *stream_info; enum msm_vfe_axi_state valid_state = (stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE; + + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) { + return -EINVAL; + } + for (i = 0; i < stream_cfg_cmd->num_streams; i++) { + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) + > MAX_NUM_STREAM) { + return -EINVAL; + } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; spin_lock_irqsave(&stream_info->lock, flags); @@ -840,7 +849,16 @@ static void msm_isp_update_camif_output_count( int i; struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) { + return; + } + for (i = 0; i < stream_cfg_cmd->num_streams; i++) { + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) + > MAX_NUM_STREAM) { + return; + } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; @@ -1020,7 +1038,16 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, uint32_t wm_reload_mask = 0x0; struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) { + return -EINVAL; + } + for (i = 0; i < stream_cfg_cmd->num_streams; i++) { + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) + > MAX_NUM_STREAM) { + return -EINVAL; + } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; src_state = axi_data->src_info[ @@ -1073,7 +1100,16 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, uint8_t wait_for_complete = 0; struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) { + return -EINVAL; + } + for (i = 0; i < stream_cfg_cmd->num_streams; i++) { + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) + > MAX_NUM_STREAM) { + return -EINVAL; + } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; @@ -1158,8 +1194,18 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) return -EBUSY; } + /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/ + if (update_cmd->num_streams > MAX_NUM_STREAM) { + return -EINVAL; + } + for (i = 0; i < update_cmd->num_streams; i++) { update_info = &update_cmd->update_info[i]; + /*check array reference bounds*/ + if (HANDLE_TO_IDX(update_info->stream_handle) + > MAX_NUM_STREAM) { + return -EINVAL; + } stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(update_info->stream_handle)]; if (stream_info->state != ACTIVE && -- cgit v1.1