hwmon: (w83792d) Fix NULL pointer dereference by removing unnecessary structure field
authorNadezda Lutovinova <lutovinova@ispras.ru>
Tue, 21 Sep 2021 15:51:52 +0000 (18:51 +0300)
committerGuenter Roeck <linux@roeck-us.net>
Sat, 2 Oct 2021 12:12:05 +0000 (05:12 -0700)
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>
drivers/hwmon/w83792d.c

index abd5c3a..1f175f3 100644 (file)
@@ -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_client *new_client)
        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_client *new_client)
        }
 
        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;
 }