OSDN Git Service

msm: ais: isp: Handling buffer use after getting it freed
authorSuprith Malligere Shankaregowda <supgow@codeaurora.org>
Wed, 25 Apr 2018 05:47:30 +0000 (11:17 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Wed, 2 May 2018 06:17:58 +0000 (23:17 -0700)
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 <supgow@codeaurora.org>
drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c
drivers/media/platform/msm/ais/isp/msm_isp_stats_util.c

index 22820a0..77f2ab5 100644 (file)
@@ -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);
index 0d08cff..360eb8e 100644 (file)
@@ -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);