]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
hwmon: (sht3x) Fix unaligned accesses
authorGuenter Roeck <linux@roeck-us.net>
Sat, 25 Jul 2026 16:34:46 +0000 (09:34 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 27 Jul 2026 18:35:18 +0000 (11:35 -0700)
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: 7c84f7f80d6f ("hwmon: add support for Sensirion SHT3x sensors")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/sht3x.c

index c2f6b73aa7f34a67257c60137c90acf14596c696..4d90f89a9929701fad80632903859b318e045426 100644 (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,