summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSarada Prasanna Garnayak <sgarna@codeaurora.org>2017-06-08 15:34:13 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-06-22 00:35:59 -0700
commit470cbd2aeabd076d7278d25b15e130767e67dc44 (patch)
treee2b3db4c32b61817095b9f491a5005b6d7431db0 /drivers
parent560a996da5c0bf398d2fba51e9909cd7323afea8 (diff)
icnss: fix the memory and kernel info leak due to the race condition
The icnss register read/write debugfs entry can be accessed by multiple user space thread. Memory allocation and deallocation in the register read/write file operation leads to potential memory leak during concurrency access of debugfs device file. Add protection to avoid the memory leak and kernel information leak due to the race condition in the register read/write ops. CRs-Fixed: 2012572 Change-Id: I22c6af9a396c0df4e68f75702fc68a5dff5af032 Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/soc/qcom/icnss.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 28f89bfac7c6..9690d3c64560 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -434,6 +434,7 @@ static struct icnss_priv {
bool is_wlan_mac_set;
struct icnss_wlan_mac_addr wlan_mac_addr;
bool bypass_s1_smmu;
+ struct mutex dev_lock;
} *penv;
#ifdef CONFIG_ICNSS_DEBUG
@@ -3939,12 +3940,14 @@ static int icnss_regread_show(struct seq_file *s, void *data)
{
struct icnss_priv *priv = s->private;
+ mutex_lock(&priv->dev_lock);
if (!priv->diag_reg_read_buf) {
seq_puts(s, "Usage: echo <mem_type> <offset> <data_len> > <debugfs>/icnss/reg_read\n");
if (!test_bit(ICNSS_FW_READY, &priv->state))
seq_puts(s, "Firmware is not ready yet!, wait for FW READY\n");
+ mutex_unlock(&priv->dev_lock);
return 0;
}
@@ -3958,6 +3961,7 @@ static int icnss_regread_show(struct seq_file *s, void *data)
priv->diag_reg_read_len = 0;
kfree(priv->diag_reg_read_buf);
priv->diag_reg_read_buf = NULL;
+ mutex_unlock(&priv->dev_lock);
return 0;
}
@@ -4018,18 +4022,22 @@ static ssize_t icnss_regread_write(struct file *fp, const char __user *user_buf,
data_len > QMI_WLFW_MAX_DATA_SIZE_V01)
return -EINVAL;
+ mutex_lock(&priv->dev_lock);
kfree(priv->diag_reg_read_buf);
priv->diag_reg_read_buf = NULL;
reg_buf = kzalloc(data_len, GFP_KERNEL);
- if (!reg_buf)
+ if (!reg_buf) {
+ mutex_unlock(&priv->dev_lock);
return -ENOMEM;
+ }
ret = wlfw_athdiag_read_send_sync_msg(priv, reg_offset,
mem_type, data_len,
reg_buf);
if (ret) {
kfree(reg_buf);
+ mutex_unlock(&priv->dev_lock);
return ret;
}
@@ -4037,6 +4045,7 @@ static ssize_t icnss_regread_write(struct file *fp, const char __user *user_buf,
priv->diag_reg_read_mem_type = mem_type;
priv->diag_reg_read_len = data_len;
priv->diag_reg_read_buf = reg_buf;
+ mutex_unlock(&priv->dev_lock);
return count;
}
@@ -4284,6 +4293,7 @@ static int icnss_probe(struct platform_device *pdev)
spin_lock_init(&priv->event_lock);
spin_lock_init(&priv->on_off_lock);
+ mutex_init(&priv->dev_lock);
priv->event_wq = alloc_workqueue("icnss_driver_event", WQ_UNBOUND, 1);
if (!priv->event_wq) {