| From 0f36b88173f028e372668ae040ab1a496834d278 Mon Sep 17 00:00:00 2001 |
| From: Nadezda Lutovinova <lutovinova@ispras.ru> |
| Date: Tue, 21 Sep 2021 18:51:52 +0300 |
| Subject: hwmon: (w83792d) Fix NULL pointer dereference by removing unnecessary structure field |
| |
| From: Nadezda Lutovinova <lutovinova@ispras.ru> |
| |
| commit 0f36b88173f028e372668ae040ab1a496834d278 upstream. |
| |
| If driver read val value sufficient for |
| (val & 0x08) && (!(val & 0x80)) && ((val & 0x7) == ((val >> 4) & 0x7)) |
| from device then Null pointer dereference occurs. |
| (It is possible if tmp = 0b0xyz1xyz, where same literals mean same numbers) |
| Also lm75[] does not serve a purpose anymore after switching to |
| devm_i2c_new_dummy_device() in w83791d_detect_subclients(). |
| |
| The patch fixes possible NULL pointer dereference by removing lm75[]. |
| |
| Found by Linux Driver Verification project (linuxtesting.org). |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Nadezda Lutovinova <lutovinova@ispras.ru> |
| Link: https://lore.kernel.org/r/20210921155153.28098-2-lutovinova@ispras.ru |
| [groeck: Dropped unnecessary continuation lines, fixed multipline alignment] |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/hwmon/w83792d.c | 28 +++++++++++----------------- |
| 1 file changed, 11 insertions(+), 17 deletions(-) |
| |
| --- a/drivers/hwmon/w83792d.c |
| +++ b/drivers/hwmon/w83792d.c |
| @@ -264,9 +264,6 @@ struct w83792d_data { |
| char valid; /* !=0 if following fields are valid */ |
| unsigned long last_updated; /* In jiffies */ |
| |
| - /* array of 2 pointers to subclients */ |
| - struct i2c_client *lm75[2]; |
| - |
| u8 in[9]; /* Register value */ |
| u8 in_max[9]; /* Register value */ |
| u8 in_min[9]; /* Register value */ |
| @@ -927,7 +924,6 @@ w83792d_detect_subclients(struct i2c_cli |
| int address = new_client->addr; |
| u8 val; |
| struct i2c_adapter *adapter = new_client->adapter; |
| - struct w83792d_data *data = i2c_get_clientdata(new_client); |
| |
| id = i2c_adapter_id(adapter); |
| if (force_subclients[0] == id && force_subclients[1] == address) { |
| @@ -946,21 +942,19 @@ w83792d_detect_subclients(struct i2c_cli |
| } |
| |
| val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR); |
| - if (!(val & 0x08)) |
| - data->lm75[0] = devm_i2c_new_dummy_device(&new_client->dev, adapter, |
| - 0x48 + (val & 0x7)); |
| - if (!(val & 0x80)) { |
| - if (!IS_ERR(data->lm75[0]) && |
| - ((val & 0x7) == ((val >> 4) & 0x7))) { |
| - dev_err(&new_client->dev, |
| - "duplicate addresses 0x%x, use force_subclient\n", |
| - data->lm75[0]->addr); |
| - return -ENODEV; |
| - } |
| - data->lm75[1] = devm_i2c_new_dummy_device(&new_client->dev, adapter, |
| - 0x48 + ((val >> 4) & 0x7)); |
| + |
| + if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) { |
| + dev_err(&new_client->dev, |
| + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7)); |
| + return -ENODEV; |
| } |
| |
| + if (!(val & 0x08)) |
| + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + (val & 0x7)); |
| + |
| + if (!(val & 0x80)) |
| + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + ((val >> 4) & 0x7)); |
| + |
| return 0; |
| } |
| |