dsp: add lock in ion free to avoid use after free

add lock in ion free to protect dma buff and avoid
use after free.

Change-Id: I6376408ce1a5b98b7aeacc32e44ec4db08ff9df5
Signed-off-by: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
This commit is contained in:
Prasad Kumpatla
2023-01-30 15:16:25 +05:30
committed by Gerrit - the friendly Code Review server
parent 4e4aec5874
commit 934cadd456

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/init.h>
@@ -102,6 +102,7 @@ static void msm_audio_ion_add_allocation(
mutex_unlock(&(msm_audio_ion_data->list_mutex));
}
/* This function is called with ion_data list mutex lock */
static int msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
struct msm_audio_ion_private *ion_data, struct iosys_map *iosys_vmap)
{
@@ -139,6 +140,7 @@ exit:
return rc;
}
/* This function is called with ion_data list mutex lock */
static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
dma_addr_t *addr, size_t *len, bool is_iova,
struct msm_audio_ion_private *ion_data)
@@ -231,7 +233,6 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, struct msm_audio_ion
* should be explicitly acquired to avoid race condition
* on adding elements to the list.
*/
mutex_lock(&(ion_data->list_mutex));
list_for_each_safe(ptr, next,
&(ion_data->alloc_list)) {
@@ -256,7 +257,6 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, struct msm_audio_ion
break;
}
}
mutex_unlock(&(ion_data->list_mutex));
if (!found) {
dev_err(cb_dev,
@@ -301,7 +301,6 @@ static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_
* TBD: remove the below section once new API
* for unmapping kernel virtual address is available.
*/
mutex_lock(&(ion_data->list_mutex));
list_for_each_entry(alloc_data, &(ion_data->alloc_list),
list) {
if (alloc_data->dma_buf == dma_buf) {
@@ -309,7 +308,6 @@ static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_
break;
}
}
mutex_unlock(&(ion_data->list_mutex));
if (!iosys_vmap) {
dev_err(cb_dev,
@@ -332,7 +330,8 @@ err:
return rc;
}
static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
/* This function is called with ion_data list mutex lock */
static int msm_audio_ion_buf_map(struct dma_buf *dma_buf, dma_addr_t *paddr,
size_t *plen, struct iosys_map *iosys_vmap,
struct msm_audio_ion_private *ion_data)
{
@@ -357,7 +356,9 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
pr_err("%s: ION memory mapping for AUDIO failed, err:%d\n",
__func__, rc);
rc = -ENOMEM;
mutex_lock(&(ion_data->list_mutex));
msm_audio_dma_buf_unmap(dma_buf, ion_data);
mutex_unlock(&(ion_data->list_mutex));
goto err;
}
@@ -400,6 +401,11 @@ void msm_audio_delete_fd_entry(void *handle)
struct msm_audio_fd_data *msm_audio_fd_data = NULL;
struct list_head *ptr, *next;
if (!handle) {
pr_err("%s Invalid handle\n", __func__);
return;
}
mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
list_for_each_safe(ptr, next,
&msm_audio_ion_fd_list.fd_list) {
@@ -471,6 +477,7 @@ void msm_audio_get_handle(int fd, void **handle)
pr_debug("%s fd %d\n", __func__, fd);
mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
*handle = NULL;
list_for_each_entry(msm_audio_fd_data,
&msm_audio_ion_fd_list.fd_list, list) {
if (msm_audio_fd_data->fd == fd) {
@@ -531,7 +538,7 @@ static int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
}
}
if (ion_data->smmu_enabled) {
rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, iosys_vmap, ion_data);
rc = msm_audio_ion_buf_map(*dma_buf, paddr, plen, iosys_vmap, ion_data);
if (rc) {
pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
goto err;
@@ -558,6 +565,7 @@ err:
*
* Returns 0 on success or error on failure
*/
/* This funtion is called with ion_data list mutex lock */
static int msm_audio_ion_free(struct dma_buf *dma_buf, struct msm_audio_ion_private *ion_data)
{
int ret = 0;
@@ -567,14 +575,18 @@ static int msm_audio_ion_free(struct dma_buf *dma_buf, struct msm_audio_ion_priv
return -EINVAL;
}
mutex_lock(&(ion_data->list_mutex));
if (ion_data->smmu_enabled) {
ret = msm_audio_ion_unmap_kernel(dma_buf, ion_data);
if (ret)
if (ret) {
mutex_unlock(&(ion_data->list_mutex));
return ret;
}
}
msm_audio_dma_buf_unmap(dma_buf, ion_data);
mutex_unlock(&(ion_data->list_mutex));
return 0;
}