mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store()
When an LM87 or ADM1024 device is probed with VID support enabled, reading
from or writing to the vrm sysfs attribute triggers a driver data type
confusion in vrm_show() and vrm_store() in drivers/hwmon/lm87.c.
In lm87_probe(), the driver stores the struct lm87_data pointer on the I2C
client via i2c_set_clientdata() and passes the struct i2c_client pointer as
the drvdata argument to devm_hwmon_device_register_with_groups(), which
attaches the attribute groups to the registered hwmon device with client as
its driver_data. Unlike the other sysfs callbacks that retrieve client via
dev_get_drvdata() and then obtain data via i2c_get_clientdata(), vrm_show()
and vrm_store() assign dev_get_drvdata(dev) directly to struct lm87_data *.
Dereferencing data->vrm therefore accesses the struct i2c_client instance
at offsetof(struct lm87_data, vrm), causing vrm_show() to leak an unrelated
byte from struct i2c_client to userspace and vrm_store() to corrupt a byte
within struct i2c_client while failing to update the actual VRM value.
Fix the problem by assigning the return value from dev_get_drvdata(dev) to
struct i2c_client *client and using i2c_get_clientdata() to get the actual
client data.
Fixes: 00a0c905ab ("hwmon: (lm87) Use hwmon to create the sysfs groups")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
185039b1c0
commit
5b51ff0887
|
|
@ -606,13 +606,16 @@ static DEVICE_ATTR_RO(cpu0_vid);
|
|||
static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lm87_data *data = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = dev_get_drvdata(dev);
|
||||
struct lm87_data *data = i2c_get_clientdata(client);
|
||||
|
||||
return sprintf(buf, "%d\n", data->vrm);
|
||||
}
|
||||
static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct lm87_data *data = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = dev_get_drvdata(dev);
|
||||
struct lm87_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val;
|
||||
int err;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user