[PATCH] w1_therm: verify CRC only after a full scratchpad read

From: Жамбакиев Радий Рикардинович

Date: Fri Sep 11 2026 - 04:43:02 EST


From: Radiy Zhambakiev <r.zhambakiev@xxxxxxxxxxxxxxxxx>

read_scratchpad() computes the CRC and updates verdict/ret
unconditionally after w1_read_block(), even when it failed and returned
fewer than 9 bytes without writing to info->rom.

info->rom is zeroed at the top of the function, so a failed read leaves
it all zeros. w1_calc_crc8() of eight zero bytes is 0 and info->rom[8]
is also 0, so the 'rom[8] == crc' comparison spuriously matches, verdict
is set and ret becomes 0. That makes the retry loop,
'while (max_trying-- && ret)', exit early and read_scratchpad() report
success with an all-zero scratchpad. Callers such as temperature_show()
then surface a bogus 0 degC reading instead of an error.

Only run the CRC check (and the resulting ret/verdict update) when all
9 bytes were actually read; otherwise keep the -EIO so the loop retries.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 308bdb94de0c ("w1_therm: adding resolution sysfs entry")
Signed-off-by: Radiy Zhambakiev <r.zhambakiev@xxxxxxxxxxxxxxxxx>
---
drivers/w1/slaves/w1_therm.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index d96b224e2215..fd8c067a92d4 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -1302,15 +1302,15 @@ static int read_scratchpad(struct w1_slave *sl, struct therm_info *info)
"w1_read_block(): returned %u instead of 9.\n",
nb_bytes_read);
ret = -EIO;
- }
-
- info->crc = w1_calc_crc8(info->rom, 8);
+ } else {
+ info->crc = w1_calc_crc8(info->rom, 8);

- if (info->rom[8] == info->crc) {
- info->verdict = 1;
- ret = 0;
- } else
- ret = -EIO; /* CRC not checked */
+ if (info->rom[8] == info->crc) {
+ info->verdict = 1;
+ ret = 0;
+ } else
+ ret = -EIO; /* CRC not checked */
+ }
}

}
--
2.53.0