Skip to content

Commit

Permalink
adt7470: check input range when sysfs files are written
Browse files Browse the repository at this point in the history
Implement correct range checking for adt7470 to prevent userland from
writing impossible values into the chip, and cap out-of-range values per
standard hwmon conventions.

Implement correct rounding of input values per standard hwmon conventions.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Darrick J. Wong authored and Linus Torvalds committed Nov 13, 2008
1 parent 7e036d0 commit 05a9bd4
Showing 1 changed file with 62 additions and 13 deletions.
75 changes: 62 additions & 13 deletions drivers/hwmon/adt7470.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ I2C_CLIENT_INSMOD_1(adt7470);
#define FAN_PERIOD_INVALID 65535
#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)

#define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor))

struct adt7470_data {
struct device *hwmon_dev;
struct attribute_group attrs;
Expand Down Expand Up @@ -353,7 +355,13 @@ static ssize_t set_temp_min(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10) / 1000;
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = ROUND_DIV(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->temp_min[attr->index] = temp;
Expand Down Expand Up @@ -381,7 +389,13 @@ static ssize_t set_temp_max(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10) / 1000;
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = ROUND_DIV(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->temp_max[attr->index] = temp;
Expand Down Expand Up @@ -430,11 +444,13 @@ static ssize_t set_fan_max(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;

if (!temp)
if (strict_strtol(buf, 10, &temp) || !temp)
return -EINVAL;

temp = FAN_RPM_TO_PERIOD(temp);
temp = SENSORS_LIMIT(temp, 1, 65534);

mutex_lock(&data->lock);
data->fan_max[attr->index] = temp;
Expand Down Expand Up @@ -465,11 +481,13 @@ static ssize_t set_fan_min(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;

if (!temp)
if (strict_strtol(buf, 10, &temp) || !temp)
return -EINVAL;

temp = FAN_RPM_TO_PERIOD(temp);
temp = SENSORS_LIMIT(temp, 1, 65534);

mutex_lock(&data->lock);
data->fan_min[attr->index] = temp;
Expand Down Expand Up @@ -507,9 +525,12 @@ static ssize_t set_force_pwm_max(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;
u8 reg;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

mutex_lock(&data->lock);
data->force_pwm_max = temp;
reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
Expand Down Expand Up @@ -537,7 +558,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->pwm[attr->index] = temp;
Expand All @@ -564,7 +590,12 @@ static ssize_t set_pwm_max(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->pwm_max[attr->index] = temp;
Expand Down Expand Up @@ -592,7 +623,12 @@ static ssize_t set_pwm_min(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->pwm_min[attr->index] = temp;
Expand Down Expand Up @@ -630,7 +666,13 @@ static ssize_t set_pwm_tmin(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10) / 1000;
long temp;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = ROUND_DIV(temp, 1000);
temp = SENSORS_LIMIT(temp, 0, 255);

mutex_lock(&data->lock);
data->pwm_tmin[attr->index] = temp;
Expand Down Expand Up @@ -658,11 +700,14 @@ static ssize_t set_pwm_auto(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index);
int pwm_auto_reg_mask;
long temp;
u8 reg;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

if (attr->index % 2)
pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK;
else
Expand Down Expand Up @@ -716,10 +761,14 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
int temp = cvt_auto_temp(simple_strtol(buf, NULL, 10));
int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index);
long temp;
u8 reg;

if (strict_strtol(buf, 10, &temp))
return -EINVAL;

temp = cvt_auto_temp(temp);
if (temp < 0)
return temp;

Expand Down

0 comments on commit 05a9bd4

Please sign in to comment.