Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (w83791d) Fix NULL pointer dereference by removing unnecessary structure field

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-1-lutovinova@ispras.ru
[groeck: Dropped unnecessary continuation lines, fixed multi-line alignment]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Nadezda Lutovinova and committed by
Guenter Roeck
943c15ac 2292e2f6

+11 -18
+11 -18
drivers/hwmon/w83791d.c
··· 273 273 char valid; /* !=0 if following fields are valid */ 274 274 unsigned long last_updated; /* In jiffies */ 275 275 276 - /* array of 2 pointers to subclients */ 277 - struct i2c_client *lm75[2]; 278 - 279 276 /* volts */ 280 277 u8 in[NUMBER_OF_VIN]; /* Register value */ 281 278 u8 in_max[NUMBER_OF_VIN]; /* Register value */ ··· 1254 1257 static int w83791d_detect_subclients(struct i2c_client *client) 1255 1258 { 1256 1259 struct i2c_adapter *adapter = client->adapter; 1257 - struct w83791d_data *data = i2c_get_clientdata(client); 1258 1260 int address = client->addr; 1259 1261 int i, id; 1260 1262 u8 val; ··· 1276 1280 } 1277 1281 1278 1282 val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); 1279 - if (!(val & 0x08)) 1280 - data->lm75[0] = devm_i2c_new_dummy_device(&client->dev, adapter, 1281 - 0x48 + (val & 0x7)); 1282 - if (!(val & 0x80)) { 1283 - if (!IS_ERR(data->lm75[0]) && 1284 - ((val & 0x7) == ((val >> 4) & 0x7))) { 1285 - dev_err(&client->dev, 1286 - "duplicate addresses 0x%x, " 1287 - "use force_subclient\n", 1288 - data->lm75[0]->addr); 1289 - return -ENODEV; 1290 - } 1291 - data->lm75[1] = devm_i2c_new_dummy_device(&client->dev, adapter, 1292 - 0x48 + ((val >> 4) & 0x7)); 1283 + 1284 + if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) { 1285 + dev_err(&client->dev, 1286 + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7)); 1287 + return -ENODEV; 1293 1288 } 1289 + 1290 + if (!(val & 0x08)) 1291 + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + (val & 0x7)); 1292 + 1293 + if (!(val & 0x80)) 1294 + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + ((val >> 4) & 0x7)); 1294 1295 1295 1296 return 0; 1296 1297 }