drivers: thermal: validate cdev sysfs state request before using it

There is a chance that userspace cooling device cur_state or
min_state sysfs node can request any random value. It may be
a value greater than max supported state. In that case if
cooling device is not bailing out, cooling device stats module
may behave unexpectedly.

Validate whether cur_state or min_state request is within the
range of max supported state or not for each cooling device.
If it is greater than max_state, bail out for that request for
different cooling devices.

Change-Id: If6422327b2bf4235617203588a5fe5805bf918f2
Signed-off-by: Gopala Krishna Nuthaki <quic_gnuthaki@quicinc.com>
This commit is contained in:
Gopala Krishna Nuthaki 2022-01-10 18:43:50 +05:30
parent 93e270aae4
commit 73d583e72a
4 changed files with 15 additions and 11 deletions

View File

@ -5,6 +5,7 @@
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
*
* Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org>
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or modify
@ -364,7 +365,7 @@ static int cpufreq_set_min_state(struct thermal_cooling_device *cdev,
unsigned int floor_freq;
if (state > cpufreq_cdev->max_level)
state = cpufreq_cdev->max_level;
return -EINVAL;
if (cpufreq_cdev->cpufreq_floor_state == state)
return 0;

View File

@ -3,6 +3,7 @@
* devfreq
*
* Copyright (C) 2014-2015 ARM Limited
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 as
@ -140,14 +141,14 @@ static int devfreq_cooling_set_min_state(struct thermal_cooling_device *cdev,
struct device *dev = df->dev.parent;
int ret;
if (state >= dfc->freq_table_size)
return -EINVAL;
if (state == dfc->cooling_min_state)
return 0;
dev_dbg(dev, "Setting cooling min state %lu\n", state);
if (state >= dfc->freq_table_size)
state = dfc->freq_table_size - 1;
ret = partition_enable_opps(dfc, dfc->cooling_state, state);
if (ret)
return ret;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
@ -270,12 +271,12 @@ static int qmi_set_cur_state(struct thermal_cooling_device *cdev,
if (!qmi_cdev)
return -EINVAL;
if (qmi_cdev->type == QMI_CDEV_MIN_LIMIT_TYPE)
return 0;
if (state > qmi_cdev->max_level)
return -EINVAL;
if (qmi_cdev->type == QMI_CDEV_MIN_LIMIT_TYPE)
return 0;
return qmi_set_cur_or_min_state(qmi_cdev, state);
}
@ -287,12 +288,12 @@ static int qmi_set_min_state(struct thermal_cooling_device *cdev,
if (!qmi_cdev)
return -EINVAL;
if (state > qmi_cdev->max_level)
return -EINVAL;
if (qmi_cdev->type == QMI_CDEV_MAX_LIMIT_TYPE)
return 0;
if (state > qmi_cdev->max_level)
state = qmi_cdev->max_level;
/* Convert state into QMI client expects for min state */
state = qmi_cdev->max_level - state;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
@ -95,7 +96,7 @@ static int rpm_smd_set_cur_state(struct thermal_cooling_device *cdev,
int ret = 0;
if (state > (RPM_SMD_TEMP_MAX_NR - 1))
state = RPM_SMD_TEMP_MAX_NR - 1;
return -EINVAL;
ret = rpm_smd_send_request_to_rpm(rpm_smd_dev, (unsigned int)state);
if (ret)