Skip to content
/ linux Public

Commit 81f61e3

Browse files
Sanman Pradhangregkh
authored andcommitted
hwmon: (pmbus/mp2869) Check pmbus_read_byte_data() before using its return value
commit c6f45ed upstream. In mp2869_read_byte_data() and mp2869_read_word_data(), the return value of pmbus_read_byte_data() for PMBUS_STATUS_MFR_SPECIFIC is used directly inside FIELD_GET() macro arguments without error checking. If the I2C transaction fails, a negative error code is passed to FIELD_GET() and FIELD_PREP(), silently corrupting the status register bits being constructed. Extract the nested pmbus_read_byte_data() calls into a separate variable and check for errors before use. This also eliminates a redundant duplicate read of the same register in the PMBUS_STATUS_TEMPERATURE case. Fixes: a3a2923 ("hwmon: add MP2869,MP29608,MP29612 and MP29816 series driver") Cc: stable@vger.kernel.org Signed-off-by: Sanman Pradhan <psanman@juniper.net> Link: https://lore.kernel.org/r/20260317173308.382545-4-sanman.pradhan@hpe.com Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 48fed64 commit 81f61e3

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

drivers/hwmon/pmbus/mp2869.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static int mp2869_read_byte_data(struct i2c_client *client, int page, int reg)
165165
{
166166
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
167167
struct mp2869_data *data = to_mp2869_data(info);
168-
int ret;
168+
int ret, mfr;
169169

170170
switch (reg) {
171171
case PMBUS_VOUT_MODE:
@@ -188,11 +188,14 @@ static int mp2869_read_byte_data(struct i2c_client *client, int page, int reg)
188188
if (ret < 0)
189189
return ret;
190190

191+
mfr = pmbus_read_byte_data(client, page,
192+
PMBUS_STATUS_MFR_SPECIFIC);
193+
if (mfr < 0)
194+
return mfr;
195+
191196
ret = (ret & ~GENMASK(2, 2)) |
192197
FIELD_PREP(GENMASK(2, 2),
193-
FIELD_GET(GENMASK(1, 1),
194-
pmbus_read_byte_data(client, page,
195-
PMBUS_STATUS_MFR_SPECIFIC)));
198+
FIELD_GET(GENMASK(1, 1), mfr));
196199
break;
197200
case PMBUS_STATUS_TEMPERATURE:
198201
/*
@@ -207,15 +210,16 @@ static int mp2869_read_byte_data(struct i2c_client *client, int page, int reg)
207210
if (ret < 0)
208211
return ret;
209212

213+
mfr = pmbus_read_byte_data(client, page,
214+
PMBUS_STATUS_MFR_SPECIFIC);
215+
if (mfr < 0)
216+
return mfr;
217+
210218
ret = (ret & ~GENMASK(7, 6)) |
211219
FIELD_PREP(GENMASK(6, 6),
212-
FIELD_GET(GENMASK(1, 1),
213-
pmbus_read_byte_data(client, page,
214-
PMBUS_STATUS_MFR_SPECIFIC))) |
220+
FIELD_GET(GENMASK(1, 1), mfr)) |
215221
FIELD_PREP(GENMASK(7, 7),
216-
FIELD_GET(GENMASK(1, 1),
217-
pmbus_read_byte_data(client, page,
218-
PMBUS_STATUS_MFR_SPECIFIC)));
222+
FIELD_GET(GENMASK(1, 1), mfr));
219223
break;
220224
default:
221225
ret = -ENODATA;
@@ -230,7 +234,7 @@ static int mp2869_read_word_data(struct i2c_client *client, int page, int phase,
230234
{
231235
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
232236
struct mp2869_data *data = to_mp2869_data(info);
233-
int ret;
237+
int ret, mfr;
234238

235239
switch (reg) {
236240
case PMBUS_STATUS_WORD:
@@ -246,11 +250,14 @@ static int mp2869_read_word_data(struct i2c_client *client, int page, int phase,
246250
if (ret < 0)
247251
return ret;
248252

253+
mfr = pmbus_read_byte_data(client, page,
254+
PMBUS_STATUS_MFR_SPECIFIC);
255+
if (mfr < 0)
256+
return mfr;
257+
249258
ret = (ret & ~GENMASK(2, 2)) |
250259
FIELD_PREP(GENMASK(2, 2),
251-
FIELD_GET(GENMASK(1, 1),
252-
pmbus_read_byte_data(client, page,
253-
PMBUS_STATUS_MFR_SPECIFIC)));
260+
FIELD_GET(GENMASK(1, 1), mfr));
254261
break;
255262
case PMBUS_READ_VIN:
256263
/*

0 commit comments

Comments
 (0)