drivers: soc: qcom: rpm_stats: Add mutex lock for shared data
The buffer allocated in rpmstats_show need to be protected as there can be a possiblity of use-after-free scenario. Process A B | | open | | | read started | | close Add mutex lock to protect the buffer to avoid this. Also allow reading RPM stats information using sysfs nodes. The stats are available at /sys/power/system_sleep/stats Change-Id: I28ab98e264fc4e425f23c71ddc6dcc8f275d8f6b Signed-off-by: Naresh Malladi <namall@codeaurora.org>
This commit is contained in:
parent
fa173fa679
commit
a9dcbcf326
|
@ -389,22 +389,26 @@ static ssize_t rpmstats_show(struct kobject *kobj,
|
|||
{
|
||||
struct msm_rpmstats_private_data *prvdata = NULL;
|
||||
struct msm_rpmstats_platform_data *pdata = NULL;
|
||||
ssize_t ret;
|
||||
|
||||
mutex_lock(&rpm_stats_mutex);
|
||||
pdata = GET_PDATA_OF_ATTR(attr);
|
||||
|
||||
prvdata =
|
||||
kmalloc(sizeof(*prvdata), GFP_KERNEL);
|
||||
if (!prvdata)
|
||||
return -ENOMEM;
|
||||
if (!prvdata) {
|
||||
ret = -ENOMEM;
|
||||
goto kmalloc_fail;
|
||||
}
|
||||
|
||||
prvdata->reg_base = ioremap_nocache(pdata->phys_addr_base,
|
||||
pdata->phys_size);
|
||||
if (!prvdata->reg_base) {
|
||||
kfree(prvdata);
|
||||
pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n",
|
||||
__func__, &pdata->phys_addr_base,
|
||||
pdata->phys_size);
|
||||
return -EBUSY;
|
||||
ret = -EBUSY;
|
||||
goto ioremap_fail;
|
||||
}
|
||||
|
||||
prvdata->read_idx = prvdata->num_records = prvdata->len = 0;
|
||||
|
@ -426,23 +430,22 @@ static ssize_t rpmstats_show(struct kobject *kobj,
|
|||
prvdata);
|
||||
}
|
||||
|
||||
return snprintf(buf, prvdata->len, prvdata->buf);
|
||||
ret = snprintf(buf, prvdata->len, prvdata->buf);
|
||||
iounmap(prvdata->reg_base);
|
||||
ioremap_fail:
|
||||
kfree(prvdata);
|
||||
kmalloc_fail:
|
||||
mutex_unlock(&rpm_stats_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd)
|
||||
{
|
||||
struct kobject *module_kobj = NULL;
|
||||
struct kobject *rpmstats_kobj = NULL;
|
||||
struct msm_rpmstats_kobj_attr *rpms_ka = NULL;
|
||||
int ret = 0;
|
||||
|
||||
module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
|
||||
if (!module_kobj) {
|
||||
pr_err("%s: Cannot find module_kset\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rpmstats_kobj = kobject_create_and_add("rpmstats", module_kobj);
|
||||
rpmstats_kobj = kobject_create_and_add("system_sleep", power_kobj);
|
||||
if (!rpmstats_kobj) {
|
||||
pr_err("%s: Cannot create rpmstats kobject\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
|
|
Loading…
Reference in New Issue