diff mbox series

[01/10] hwmon: (amc6821) Stop accepting invalid pwm values

Message ID 20240628151346.1152838-2-linux@roeck-us.net (mailing list archive)
State Superseded
Headers show
Series hwmon: (amc6821) Various improvements | expand

Commit Message

Guenter Roeck June 28, 2024, 3:13 p.m. UTC
The pwm value range is well defined from 0..255. Don't accept
any values outside this range.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/amc6821.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Comments

Quentin Schulz July 1, 2024, 10:19 a.m. UTC | #1
Hi Guenter,

On 6/28/24 5:13 PM, Guenter Roeck wrote:
> The pwm value range is well defined from 0..255. Don't accept
> any values outside this range.
> 
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>   drivers/hwmon/amc6821.c | 14 ++++++++++----
>   1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
> index 9b02b304c2f5..3c614a0bd192 100644
> --- a/drivers/hwmon/amc6821.c
> +++ b/drivers/hwmon/amc6821.c
> @@ -360,8 +360,11 @@ static ssize_t pwm1_store(struct device *dev,
>   	if (ret)
>   		return ret;
>   
> +	if (val < 0 || val > 255)
> +		return -EINVAL;
> +

Why not use kstrtoul to avoid having to check for negative val? The same 
way that is done just below in this patch?

Additionally, why not using kstrtou8 so we don't have to do this check 
ourselves in the driver?

>   	mutex_lock(&data->update_lock);
> -	data->pwm1 = clamp_val(val , 0, 255);
> +	data->pwm1 = val;
>   	i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
>   	mutex_unlock(&data->update_lock);
>   	return count;
> @@ -558,13 +561,16 @@ static ssize_t pwm1_auto_point_pwm_store(struct device *dev,
>   	struct amc6821_data *data = dev_get_drvdata(dev);
>   	struct i2c_client *client = data->client;
>   	int dpwm;
> -	long val;
> -	int ret = kstrtol(buf, 10, &val);
> +	unsigned long val;
> +	int ret = kstrtoul(buf, 10, &val);

Same remark concerning kstrtou8 use.

>   	if (ret)
>   		return ret;
>   
> +	if (val > 255)
> +		return -EINVAL;
> +
>   	mutex_lock(&data->update_lock);
> -	data->pwm1_auto_point_pwm[1] = clamp_val(val, 0, 254);

We're suddenly allowing 255 as a valid value.

I don't see 255 triggering an obvious divide-by-0 issue in the code, nor 
any limitation from a quick look at the datasheet. 254 was introduced in 
the introducing commit, as well as the other 255... so probably an 
oversight by the original author? In any case, I would make this a 
separate commit or at the very least make this explicit in the commit 
log to show this isn't an oversight **right now** and that this change 
was desired.

Cheers,
Quentin
Guenter Roeck July 1, 2024, 1:50 p.m. UTC | #2
On 7/1/24 03:19, Quentin Schulz wrote:
> Hi Guenter,
> 
> On 6/28/24 5:13 PM, Guenter Roeck wrote:
>> The pwm value range is well defined from 0..255. Don't accept
>> any values outside this range.
>>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> ---
>>   drivers/hwmon/amc6821.c | 14 ++++++++++----
>>   1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
>> index 9b02b304c2f5..3c614a0bd192 100644
>> --- a/drivers/hwmon/amc6821.c
>> +++ b/drivers/hwmon/amc6821.c
>> @@ -360,8 +360,11 @@ static ssize_t pwm1_store(struct device *dev,
>>       if (ret)
>>           return ret;
>> +    if (val < 0 || val > 255)
>> +        return -EINVAL;
>> +
> 
> Why not use kstrtoul to avoid having to check for negative val? The same way that is done just below in this patch?
> 
> Additionally, why not using kstrtou8 so we don't have to do this check ourselves in the driver?
> 

Following my desire to minimize changes, but you have a point. I'll use kstrtou8().

>>       mutex_lock(&data->update_lock);
>> -    data->pwm1 = clamp_val(val , 0, 255);
>> +    data->pwm1 = val;
>>       i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
>>       mutex_unlock(&data->update_lock);
>>       return count;
>> @@ -558,13 +561,16 @@ static ssize_t pwm1_auto_point_pwm_store(struct device *dev,
>>       struct amc6821_data *data = dev_get_drvdata(dev);
>>       struct i2c_client *client = data->client;
>>       int dpwm;
>> -    long val;
>> -    int ret = kstrtol(buf, 10, &val);
>> +    unsigned long val;
>> +    int ret = kstrtoul(buf, 10, &val);
> 
> Same remark concerning kstrtou8 use.
> 
I'll use kstrtou8().

>>       if (ret)
>>           return ret;
>> +    if (val > 255)
>> +        return -EINVAL;
>> +
>>       mutex_lock(&data->update_lock);
>> -    data->pwm1_auto_point_pwm[1] = clamp_val(val, 0, 254);
> 
> We're suddenly allowing 255 as a valid value.
> 
> I don't see 255 triggering an obvious divide-by-0 issue in the code, nor any limitation from a quick look at the datasheet. 254 was introduced in the introducing commit, as well as the other 255... so probably an oversight by the original author? In any case, I would make this a separate commit or at the very least make this explicit in the commit log to show this isn't an oversight **right now** and that this change was desired.
> 

No, this is on purpose. pwm1_auto_point_pwm[2] is set to a constant
255, and pwm1_auto_point_pwm[1] has to be lower than that. As you had
noticed, I fixed this in a later commit, but I should have fixed it
here.

Thanks,
Guenter
diff mbox series

Patch

diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
index 9b02b304c2f5..3c614a0bd192 100644
--- a/drivers/hwmon/amc6821.c
+++ b/drivers/hwmon/amc6821.c
@@ -360,8 +360,11 @@  static ssize_t pwm1_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (val < 0 || val > 255)
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
-	data->pwm1 = clamp_val(val , 0, 255);
+	data->pwm1 = val;
 	i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -558,13 +561,16 @@  static ssize_t pwm1_auto_point_pwm_store(struct device *dev,
 	struct amc6821_data *data = dev_get_drvdata(dev);
 	struct i2c_client *client = data->client;
 	int dpwm;
-	long val;
-	int ret = kstrtol(buf, 10, &val);
+	unsigned long val;
+	int ret = kstrtoul(buf, 10, &val);
 	if (ret)
 		return ret;
 
+	if (val > 255)
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
-	data->pwm1_auto_point_pwm[1] = clamp_val(val, 0, 254);
+	data->pwm1_auto_point_pwm[1] = val;
 	if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP,
 			data->pwm1_auto_point_pwm[1])) {
 		dev_err(&client->dev, "Register write error, aborting.\n");