hwmon: (sht3x) Fix unaligned accesses

Sashiko reports:

In sht3x_update_client(), the 16-bit temperature and humidity values are
extracted from a stack-allocated byte array using be16_to_cpup(). The
pointers passed to this function are calculated as buf and buf + 3. Since
the difference between the two pointers is an odd number of bytes, at
least one of them is guaranteed to be at an unaligned offset.

This will trigger an alignment fault on strict-alignment architectures
such as ARMv5 or SPARC, resulting in a kernel panic.

Fix the problem by using get_unaligned_be16() instead of be16_to_cpup(),
and put_unaligned_be16() instead of cpu_to_be16().

Fixes: 7c84f7f80d ("hwmon: add support for Sensirion SHT3x sensors")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Guenter Roeck 2026-07-25 09:34:46 -07:00
parent 00feb1cce9
commit f46d5ab43a

View File

@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/unaligned.h>
/* commands (high repeatability mode) */
static const unsigned char sht3x_cmd_measure_single_hpm[] = { 0x24, 0x00 };
@ -276,9 +277,9 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
if (ret)
goto out;
val = be16_to_cpup((__be16 *)buf);
val = get_unaligned_be16(buf);
data->temperature = sht3x_extract_temperature(val);
val = be16_to_cpup((__be16 *)(buf + 3));
val = get_unaligned_be16(buf + 3);
data->humidity = sht3x_extract_humidity(val);
data->last_update = jiffies;
}
@ -336,7 +337,7 @@ static int limits_update(struct sht3x_data *data)
if (ret)
return ret;
raw = be16_to_cpup((__be16 *)buffer);
raw = get_unaligned_be16(buffer);
temperature = sht3x_extract_temperature((raw & 0x01ff) << 7);
humidity = sht3x_extract_humidity(raw & 0xfe00);
data->temperature_limits[index] = temperature;
@ -389,7 +390,7 @@ static size_t limit_write(struct device *dev,
raw = ((u32)(temperature + 45000) * 24543) >> (16 + 7);
raw |= ((humidity * 42950) >> 16) & 0xfe00;
*((__be16 *)position) = cpu_to_be16(raw);
put_unaligned_be16(raw, position);
position += SHT3X_WORD_LEN;
*position = crc8(sht3x_crc8_table,
position - SHT3X_WORD_LEN,