Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d923d7f4 authored by Suprith Malligere Shankaregowda's avatar Suprith Malligere Shankaregowda Committed by Gerrit - the friendly Code Review server
Browse files

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: Iba53a0910d672d6e7d1fc5bad3e9fadeb3b59df8
Signed-off-by: default avatarSuprith Malligere Shankaregowda <supgow@codeaurora.org>
parent 3291921f
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
/* 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
@@ -1032,15 +1032,18 @@ int msm_vfe47_start_fetch_engine(struct vfe_device *vfe_dev,
			fe_cfg->stream_id);
		vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;

		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
			vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
		if (rc < 0 || !buf) {
			pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
				__func__, rc, buf);
			mutex_unlock(&vfe_dev->buf_mgr->lock);
			return -EINVAL;
		}
		mapped_info = buf->mapped_info[0];
		buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
		mutex_unlock(&vfe_dev->buf_mgr->lock);
	} else {
		rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
			&mapped_info, fe_cfg->fd);
@@ -1090,15 +1093,18 @@ int msm_vfe47_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
			fe_cfg->stream_id);
		vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;

		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
			vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
		if (rc < 0 || !buf) {
			pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
				__func__, rc, buf);
			mutex_unlock(&vfe_dev->buf_mgr->lock);
			return -EINVAL;
		}
		mapped_info = buf->mapped_info[0];
		buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
		mutex_unlock(&vfe_dev->buf_mgr->lock);
	} else {
		rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
			&mapped_info, fe_cfg->fd);
+5 −1
Original line number Diff line number Diff line
/* 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
@@ -3830,10 +3830,12 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
				&update_cmd->update_info[i];
			stream_info = &axi_data->stream_info[HANDLE_TO_IDX(
				update_info->stream_handle)];
			mutex_lock(&vfe_dev->buf_mgr->lock);
			rc = msm_isp_request_frame(vfe_dev, stream_info,
				update_info->user_stream_id,
				update_info->frame_id,
				MSM_ISP_INVALID_BUF_INDEX);
			mutex_unlock(&vfe_dev->buf_mgr->lock);
			if (rc)
				pr_err("%s failed to request frame!\n",
					__func__);
@@ -3906,10 +3908,12 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)

		stream_info = &axi_data->stream_info[HANDLE_TO_IDX(
				req_frm->stream_handle)];
		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = msm_isp_request_frame(vfe_dev, stream_info,
			req_frm->user_stream_id,
			req_frm->frame_id,
			req_frm->buf_index);
		mutex_unlock(&vfe_dev->buf_mgr->lock);
		if (rc)
			pr_err("%s failed to request frame!\n",
				__func__);
+9 −1
Original line number Diff line number Diff line
/* 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
@@ -393,8 +393,10 @@ static int msm_isp_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
			0, 1);
		msm_isp_reset_framedrop(vfe_dev, stream_info);

		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = msm_isp_cfg_offline_ping_pong_address(vfe_dev, stream_info,
			VFE_PING_FLAG, fe_cfg->output_buf_idx);
		mutex_unlock(&vfe_dev->buf_mgr->lock);
		if (rc < 0) {
			pr_err("%s: Fetch engine config failed\n", __func__);
			return -EINVAL;
@@ -916,7 +918,9 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
		break;
	case VIDIOC_MSM_ISP_CFG_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = msm_isp_cfg_axi_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->buf_mgr->lock);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_CFG_HW_STATE:
@@ -946,6 +950,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
		break;
	case VIDIOC_MSM_ISP_AXI_RESTART:
		mutex_lock(&vfe_dev->core_mutex);
		mutex_lock(&vfe_dev->buf_mgr->lock);
		if (atomic_read(&vfe_dev->error_info.overflow_state)
			!= HALT_ENFORCED) {
			rc = msm_isp_stats_restart(vfe_dev);
@@ -956,6 +961,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
			pr_err_ratelimited("%s: no AXI restart, halt enforced.\n",
				__func__);
		}
		mutex_unlock(&vfe_dev->buf_mgr->lock);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_INPUT_CFG:
@@ -1015,7 +1021,9 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
		break;
	case VIDIOC_MSM_ISP_CFG_STATS_STREAM:
		mutex_lock(&vfe_dev->core_mutex);
		mutex_lock(&vfe_dev->buf_mgr->lock);
		rc = msm_isp_cfg_stats_stream(vfe_dev, arg);
		mutex_unlock(&vfe_dev->buf_mgr->lock);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
	case VIDIOC_MSM_ISP_UPDATE_STATS_STREAM: