From: David Laight <david.laight.linux@gmail.com>
To: "Pradhan, Sanman" <sanman.pradhan@hpe.com>
Cc: "linux-hwmon@vger.kernel.org" <linux-hwmon@vger.kernel.org>,
"linux@roeck-us.net" <linux@roeck-us.net>,
"linux@weissschuh.net" <linux@weissschuh.net>,
"cosmo.chou@quantatw.com" <cosmo.chou@quantatw.com>,
"mail@carsten-spiess.de" <mail@carsten-spiess.de>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Sanman Pradhan <psanman@juniper.net>,
"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: Re: [PATCH v2 2/3] hwmon: (isl28022) Fix integer overflow in power calculation on 32-bit
Date: Tue, 7 Apr 2026 20:21:46 +0100 [thread overview]
Message-ID: <20260407202146.59b1476f@pumpkin> (raw)
In-Reply-To: <20260407173624.247803-3-sanman.pradhan@hpe.com>
On Tue, 7 Apr 2026 17:38:01 +0000
"Pradhan, Sanman" <sanman.pradhan@hpe.com> wrote:
> From: Sanman Pradhan <psanman@juniper.net>
>
> isl28022_read_power() computes:
>
> *val = ((51200000L * ((long)data->gain)) /
> (long)data->shunt) * (long)regval;
>
> On 32-bit platforms, 'long' is 32 bits. With gain=8 and shunt=10000
> (the default configuration):
>
> (51200000 * 8) / 10000 = 40960
> 40960 * 65535 = 2,684,313,600
>
> This exceeds LONG_MAX (2,147,483,647), resulting in signed integer
> overflow.
>
> Additionally, dividing before multiplying by regval loses precision
> unnecessarily.
>
> Use u64 intermediates with div_u64() and multiply before dividing
> to retain precision. Power is inherently non-negative, so unsigned
> types are the natural fit. Clamp the result to LONG_MAX before
> returning it through the hwmon callback, following the pattern used
> by ina238.
>
> Fixes: 39671a14df4f2 ("hwmon: (isl28022) new driver for ISL28022 power monitor")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sanman Pradhan <psanman@juniper.net>
> ---
> v2:
> - Switch from s64/div_s64() to u64/div_u64() since power is
> inherently non-negative, avoiding implicit u32-to-s32 narrowing
> of the shunt divisor
There is no such thing as u32-to-s32 narrowing.
Basically nothing happens to the bit pattern.
But the values are almost certainly never negative.
>
> drivers/hwmon/isl28022.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwmon/isl28022.c b/drivers/hwmon/isl28022.c
> index c2e559dde63f..d233a7b3f327 100644
> --- a/drivers/hwmon/isl28022.c
> +++ b/drivers/hwmon/isl28022.c
> @@ -9,6 +9,7 @@
> #include <linux/err.h>
> #include <linux/hwmon.h>
> #include <linux/i2c.h>
> +#include <linux/math64.h>
> #include <linux/module.h>
> #include <linux/regmap.h>
>
> @@ -178,6 +179,7 @@ static int isl28022_read_power(struct device *dev, u32 attr, long *val)
> struct isl28022_data *data = dev_get_drvdata(dev);
> unsigned int regval;
> int err;
> + u64 tmp;
>
> switch (attr) {
> case hwmon_power_input:
> @@ -185,8 +187,9 @@ static int isl28022_read_power(struct device *dev, u32 attr, long *val)
> ISL28022_REG_POWER, ®val);
> if (err < 0)
> return err;
> - *val = ((51200000L * ((long)data->gain)) /
> - (long)data->shunt) * (long)regval;
> + tmp = (u64)51200000 * data->gain * regval;
> + tmp = div_u64(tmp, data->shunt);
> + *val = clamp_val(tmp, 0, LONG_MAX);
Don't use clamp_val(), you don't need to and it is completely
broken by design.
Just use min().
You could just write:
*val = min(div_u64(51200000ULL * data->gain * regval, data->shunt), LONG_MAX);
Have you checked that the multiply can't overflow 64bits?
That might be why the last multiply was done after the divide.
David
> break;
> default:
> return -EOPNOTSUPP;
next prev parent reply other threads:[~2026-04-07 19:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 17:37 [PATCH v2 0/3] hwmon: Fix bugs in pt5161l, isl28022, and powerz Pradhan, Sanman
2026-04-07 17:37 ` [PATCH v2 1/3] hwmon: (pt5161l) Fix bugs in pt5161l_read_block_data() Pradhan, Sanman
2026-04-07 17:38 ` [PATCH v2 2/3] hwmon: (isl28022) Fix integer overflow in power calculation on 32-bit Pradhan, Sanman
2026-04-07 19:21 ` David Laight [this message]
2026-04-07 21:21 ` Pradhan, Sanman
2026-04-08 8:42 ` David Laight
2026-04-07 17:38 ` [PATCH v2 3/3] hwmon: (powerz) Fix use-after-free and signal handling on USB disconnect Pradhan, Sanman
2026-04-07 21:22 ` Pradhan, Sanman
2026-04-07 23:38 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260407202146.59b1476f@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=cosmo.chou@quantatw.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=linux@weissschuh.net \
--cc=mail@carsten-spiess.de \
--cc=psanman@juniper.net \
--cc=sanman.pradhan@hpe.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.