From: "Thomas Weißschuh" <linux@weissschuh.net>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Benson Leung <bleung@chromium.org>,
Guenter Roeck <groeck@chromium.org>,
chrome-platform@lists.linux.dev, linux-hwmon@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] hwmon: (cros_ec) Handle temperature conversion overflows
Date: Tue, 7 Jul 2026 18:52:22 +0200 [thread overview]
Message-ID: <2b1c29c8-bf87-4113-ba1e-63e1b1d1ff51@t-8ch.de> (raw)
In-Reply-To: <7b5145a6-7054-40c7-af49-1f2415d1b83f@roeck-us.net>
On 2026-06-30 16:06:04-0700, Guenter Roeck wrote:
> On Tue, Jun 30, 2026 at 10:57:52PM +0200, Thomas Weißschuh wrote:
> > The calculations converting between the different temperature units can
> > overflow, resulting in incorrect data.
> >
> > Detect these overflows and report them.
> >
>
> I did not see how this can happen in practice, so I asked an AI agent.
> Its response is below.
>
> Given that, I am not going to apply this patch. I am all for checking
> against overflows, but only if they are real.
They can happen on 32-bit architectures.
So my idea was to have a single shared algorithm for which the compiler
will nicely optimize away the impossible cases.
(More below)
> ---
> Yes, an overflow is possible, but only on 32-bit architectures.
>
> Here is the breakdown of why this happens and its limitations:
>
> ### 1. cros_ec_hwmon_read_temp_threshold
>
> The function cros_ec_hwmon_read_temp_threshold populates the threshold variable using resp.temp_host[threshold] , which is an array of uint32_t .
>
> In cros_ec_hwmon_read , this u32 threshold is passed to the conversion function which takes a long t :
>
> static bool cros_ec_hwmon_kelvin_to_millicelsius_overflow(long t, long *ret)
>
> • On a 32-bit system: long is a 32-bit signed integer with a
> maximum value of 2,147,483,647 . If the EC hardware returns a bogus
> or uninitialized positive u32 value (e.g., 3,000,000 ), the
> multiplication t * MILLIDEGREE_PER_DEGREE ( 3,000,000 * 1000 =
> 3,000,000,000 ) will exceed LONG_MAX and cause a signed integer
> overflow.
This is the case I want to handle.
> • On a 64-bit system: long is a 64-bit integer. The maximum
> possible u32 value multiplied by 1000 is 4,294,967,295,000 ,
> which comfortably fits within the 64-bit limit of 9.22 x 10^18 . An
> overflow here is mathematically impossible.
And the compiler knows this and optimizes away the overflow checks.
>
> ### 2. A Quirky Edge Case on 32-bit
>
> If the EC returns a standard error state like 0xFFFFFFFF , the
> implicit cast from u32 threshold to long t on a 32-bit system
> will result in t = -1 .
This "standard error" state does not apply to these values.
'0' means 'disabled', all other values are normal values.
> Interestingly, the new check_mul_overflow(-1, 1000, ret) check
> will not trigger, because -1000 fits perfectly inside a 32-bit
> long . Instead, it will silently return a bogus value of -274000
> (which corresponds to -274°C). The patch does not actually prevent
> this specific "incorrect data" case.
This is a bug in my code. I'd like to fix it like below, so the compiler
can optimize this away on 64-bit, too.
if (ret == 0) {
+ if (overflows_type(threshold, long))
+ *val = LONG_MAX;
+
if (cros_ec_hwmon_kelvin_to_millicelsius_overflow(threshold, val))
*val = LONG_MAX;
> ### 3. cros_ec_hwmon_temp_to_millicelsius
>
> For the standard temperature readings (where temp is a u8 ), an
> overflow is impossible on all architectures.
> The maximum value of u8 is 255. When the offset of 200 is added,
> the maximum base is 455. Multiplying 455 * 1000 is 455,000 ,
> which easily fits in a 32-bit (and even 16-bit) integer. The patch
> author is clearly aware of this, which is why the patch asserts its
> impossibility via BUILD_BUG() :
>
> if (check_add_overflow(temp, EC_TEMP_SENSOR_OFFSET, &ret))
> BUILD_BUG();
>
> if (cros_ec_hwmon_kelvin_to_millicelsius_overflow(ret, &ret))
> BUILD_BUG();
That is correct. The idea is again to share one conversion function
between all users to avoid code duplication.
> ### Conclusion
>
> The patch's claim that calculations "can overflow" is accurate, but
> the scope of the fix is limited strictly to threshold registers
> running on 32-bit systems, and it will still emit bogus negative
> temperatures for unsigned integer values larger than LONG_MAX
> (such as 0xFFFFFFFF ).
I'll also mention that the overflow only affects 32-bit systems
and that the compiler will optimize away the checks on 64-bit.
Does that make sense?
Thomas
prev parent reply other threads:[~2026-07-07 16:52 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 20:57 [PATCH 0/2] hwmon: (cros_ec) Rework the temperature conversions Thomas Weißschuh
2026-06-30 20:57 ` [PATCH 1/2] hwmon: (cros_ec) Implement custom kelvin to celsius conversions Thomas Weißschuh
2026-06-30 23:07 ` Guenter Roeck
2026-06-30 20:57 ` [PATCH 2/2] hwmon: (cros_ec) Handle temperature conversion overflows Thomas Weißschuh
2026-06-30 23:06 ` Guenter Roeck
2026-07-07 16:52 ` Thomas Weißschuh [this message]
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=2b1c29c8-bf87-4113-ba1e-63e1b1d1ff51@t-8ch.de \
--to=linux@weissschuh.net \
--cc=bleung@chromium.org \
--cc=chrome-platform@lists.linux.dev \
--cc=groeck@chromium.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox