hwmon: (occ) Fix potential integer overflow
authorGustavo A. R. Silva <gustavo@embeddedor.com>
Mon, 7 Jan 2019 18:34:31 +0000 (12:34 -0600)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 8 Jan 2019 05:03:59 +0000 (21:03 -0800)
Cast get_unaligned_be32(...) to u64 in order to give the compiler
complete information about the proper arithmetic to use and avoid
a potential integer overflow.

Notice that such function call is used in contexts that expect
expressions of type u64 (64 bits, unsigned); and the following
expressions are currently being evaluated using 32-bit
arithmetic:

val = get_unaligned_be32(&power->update_tag) *
                        occ->powr_sample_time_us;

val = get_unaligned_be32(&power->vdn.update_tag) *
                        occ->powr_sample_time_us;

Addresses-Coverity-ID: 1442357 ("Unintentional integer overflow")
Addresses-Coverity-ID: 1442476 ("Unintentional integer overflow")
Addresses-Coverity-ID: 1442508 ("Unintentional integer overflow")
Fixes: ff692d80b2e2 ("hwmon (occ): Add sensor types and versions")
Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: Eddie James <eajames@linux.ibm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/occ/common.c

index 423903f87955510e6f8ae9cf5f583667d2335f80..391118c8aae8c7182cea59edda670b6b3bfa90a4 100644 (file)
@@ -380,8 +380,8 @@ static ssize_t occ_show_power_1(struct device *dev,
                val *= 1000000ULL;
                break;
        case 2:
-               val = get_unaligned_be32(&power->update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 3:
                val = get_unaligned_be16(&power->value) * 1000000ULL;
@@ -425,8 +425,8 @@ static ssize_t occ_show_power_2(struct device *dev,
                                       &power->update_tag);
                break;
        case 2:
-               val = get_unaligned_be32(&power->update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 3:
                val = get_unaligned_be16(&power->value) * 1000000ULL;
@@ -463,8 +463,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
                                       &power->system.update_tag);
                break;
        case 2:
-               val = get_unaligned_be32(&power->system.update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->system.update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 3:
                val = get_unaligned_be16(&power->system.value) * 1000000ULL;
@@ -477,8 +477,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
                                       &power->proc.update_tag);
                break;
        case 6:
-               val = get_unaligned_be32(&power->proc.update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->proc.update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 7:
                val = get_unaligned_be16(&power->proc.value) * 1000000ULL;
@@ -491,8 +491,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
                                       &power->vdd.update_tag);
                break;
        case 10:
-               val = get_unaligned_be32(&power->vdd.update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->vdd.update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 11:
                val = get_unaligned_be16(&power->vdd.value) * 1000000ULL;
@@ -505,8 +505,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
                                       &power->vdn.update_tag);
                break;
        case 14:
-               val = get_unaligned_be32(&power->vdn.update_tag) *
-                       occ->powr_sample_time_us;
+               val = (u64)get_unaligned_be32(&power->vdn.update_tag) *
+                          occ->powr_sample_time_us;
                break;
        case 15:
                val = get_unaligned_be16(&power->vdn.value) * 1000000ULL;