summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/qdsp6v2/voice_svc.c
diff options
context:
space:
mode:
authorAjit Pandey <ajitp@codeaurora.org>2019-02-28 18:03:17 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2019-03-22 00:18:39 -0700
commit8940467d34f9df5a5a22fad63e956dde0fb520d8 (patch)
tree3d2a03ecd5ac52d455fc1c7dcf4af1650504a258 /drivers/soc/qcom/qdsp6v2/voice_svc.c
parent1271992594e9bd18ef083f71c017087265ed3268 (diff)
drivers: soc: qcom: Added check to avoid opening multiple instance
Opening of multiple instance of voice_svc user space from app will lead to pointer deference of private data within apr callback. As multi-instance not supported added check to deny open() from user space if previous instance hasn't been closed. Change-Id: Ia5ef16c69a517760fc9d45530a8a41a333fa2a21 Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
Diffstat (limited to 'drivers/soc/qcom/qdsp6v2/voice_svc.c')
-rw-r--r--drivers/soc/qcom/qdsp6v2/voice_svc.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
index f01ab2499a75..0a49a322c9da 100644
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2019, 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
@@ -68,8 +68,9 @@ static void *dummy_q6_mvm;
static void *dummy_q6_cvs;
dev_t device_num;
+static struct mutex session_lock;
static spinlock_t voicesvc_lock;
-static bool is_released;
+static bool is_released = 1;
static int voice_svc_dummy_reg(void);
static int voice_svc_dummy_dereg(void);
@@ -645,14 +646,23 @@ static int voice_svc_dummy_dereg(void)
static int voice_svc_open(struct inode *inode, struct file *file)
{
struct voice_svc_prvt *prtd = NULL;
+ int ret = 0;
pr_debug("%s\n", __func__);
+ mutex_lock(&session_lock);
+ if (is_released == 0) {
+ pr_err("%s: Access denied to device\n", __func__);
+ ret = -EBUSY;
+ goto done;
+ }
+
prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL);
if (prtd == NULL) {
pr_err("%s: kmalloc failed\n", __func__);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto done;
}
memset(prtd, 0, sizeof(struct voice_svc_prvt));
@@ -676,7 +686,9 @@ static int voice_svc_open(struct inode *inode, struct file *file)
voice_svc_dummy_reg();
reg_dummy_sess = 1;
}
- return 0;
+done:
+ mutex_unlock(&session_lock);
+ return ret;
}
static int voice_svc_release(struct inode *inode, struct file *file)
@@ -810,6 +822,7 @@ static int voice_svc_probe(struct platform_device *pdev)
}
pr_debug("%s: Device created\n", __func__);
spin_lock_init(&voicesvc_lock);
+ mutex_init(&session_lock);
goto done;
add_err:
@@ -832,6 +845,7 @@ static int voice_svc_remove(struct platform_device *pdev)
kfree(voice_svc_dev->cdev);
device_destroy(voice_svc_class, device_num);
class_destroy(voice_svc_class);
+ mutex_destroy(&session_lock);
unregister_chrdev_region(0, MINOR_NUMBER);
return 0;