From 3945168c9c817253ca54f970decf7daf4a5096f2 Mon Sep 17 00:00:00 2001 From: Suprith Malligere Shankaregowda Date: Wed, 25 Apr 2018 11:17:30 +0530 Subject: [PATCH] msm: ais: isp: Handling buffer use after getting it freed In the code, start_fetch can try to access the buffer pointer variable after free, as the same pointer can can be freed at RELEASE_BUF call too at the same time. Hence fixing this race condition. Change-Id: I05825fb3423f95bc251e79416de50dc32cf086dc Signed-off-by: Suprith Malligere Shankaregowda --- drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c | 5 +++++ drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c index 22820a0b8e79..77f2ab5e7c3d 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c @@ -2809,9 +2809,11 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, vfe_dev->axi_data.src_info[VFE_PIX_0].eof_id = 0; } + mutex_lock(&vfe_dev->buf_mgr->lock); for (i = 0; i < stream_cfg_cmd->num_streams; i++) { if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= VFE_AXI_SRC_MAX) { + mutex_unlock(&vfe_dev->buf_mgr->lock); return -EINVAL; } stream_info = &axi_data->stream_info[ @@ -2821,6 +2823,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, SRC_TO_INTF(stream_info->stream_src)].active; else { ISP_DBG("%s: invalid src info index\n", __func__); + mutex_unlock(&vfe_dev->buf_mgr->lock); return -EINVAL; } @@ -2835,6 +2838,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, HANDLE_TO_IDX( stream_cfg_cmd->stream_handle[i])); spin_unlock_irqrestore(&stream_info->lock, flags); + mutex_unlock(&vfe_dev->buf_mgr->lock); return rc; } @@ -2893,6 +2897,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, } } + mutex_unlock(&vfe_dev->buf_mgr->lock); msm_isp_update_stream_bandwidth(vfe_dev, stream_cfg_cmd->hw_state); vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, vfe_dev->vfe_base, wm_reload_mask); diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c index 0d08cffda25c..360eb8eca8d7 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -684,18 +684,23 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, stream_cfg_cmd->num_streams); return -EINVAL; } + mutex_lock(&vfe_dev->buf_mgr->lock); + num_stats_comp_mask = vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; rc = vfe_dev->hw_info->vfe_ops.stats_ops.check_streams( stats_data->stream_info); - if (rc < 0) + if (rc < 0) { + mutex_unlock(&vfe_dev->buf_mgr->lock); return rc; + } for (i = 0; i < stream_cfg_cmd->num_streams; i++) { idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]); if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { pr_err("%s Invalid stats index %d", __func__, idx); + mutex_unlock(&vfe_dev->buf_mgr->lock); return -EINVAL; } @@ -711,11 +716,13 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, pr_err("%s: comp grp %d exceed max %d\n", __func__, stream_info->composite_flag, num_stats_comp_mask); + mutex_unlock(&vfe_dev->buf_mgr->lock); return -EINVAL; } rc = msm_isp_init_stats_ping_pong_reg(vfe_dev, stream_info); if (rc < 0) { pr_err("%s: No buffer for stream%d\n", __func__, idx); + mutex_unlock(&vfe_dev->buf_mgr->lock); return rc; } if (!stream_info->composite_flag) @@ -740,6 +747,7 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, stats_data->num_active_stream); } + mutex_unlock(&vfe_dev->buf_mgr->lock); if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) { rc = msm_isp_stats_wait_for_cfg_done(vfe_dev); -- 2.11.0