From e6fa19adf100df004bb2ee5877375773e38f909f Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 1 Dec 2022 19:12:23 +0530 Subject: [PATCH] memshare: Free QMI handle only if its valid Avoid possible use-after-free access for a QMI handle during driver deinit by ensuring the free happens only for valid QMI handle and is marked NULL post free. Change-Id: I4314dff560de2fc3aea30d636f935d7a02067a57 Signed-off-by: Manoj Prabhu B --- drivers/soc/qcom/memshare/msm_memshare.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c index cbea060ca7b6..35e600a7bad9 100644 --- a/drivers/soc/qcom/memshare/msm_memshare.c +++ b/drivers/soc/qcom/memshare/msm_memshare.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -751,6 +752,7 @@ static void memshare_init_worker(struct work_struct *work) dev_err(memsh_child->dev, "memshare: Creating mem_share_svc qmi handle failed\n"); kfree(mem_share_svc_handle); + mem_share_svc_handle = NULL; destroy_workqueue(mem_share_svc_workqueue); return; } @@ -759,8 +761,11 @@ static void memshare_init_worker(struct work_struct *work) if (rc < 0) { dev_err(memsh_child->dev, "memshare: Registering mem share svc failed %d\n", rc); - qmi_handle_release(mem_share_svc_handle); - kfree(mem_share_svc_handle); + if (mem_share_svc_handle) { + qmi_handle_release(mem_share_svc_handle); + kfree(mem_share_svc_handle); + mem_share_svc_handle = NULL; + } destroy_workqueue(mem_share_svc_workqueue); return; } @@ -917,8 +922,11 @@ static int memshare_remove(struct platform_device *pdev) return 0; flush_workqueue(mem_share_svc_workqueue); - qmi_handle_release(mem_share_svc_handle); - kfree(mem_share_svc_handle); + if (mem_share_svc_handle) { + qmi_handle_release(mem_share_svc_handle); + kfree(mem_share_svc_handle); + mem_share_svc_handle = NULL; + } destroy_workqueue(mem_share_svc_workqueue); return 0; }