[PATCH v2 3/3] rtc: ftrtc010: fix integer overflow in time calculation
From: Dan Carpenter
Date: Fri Oct 02 2026 - 07:01:28 EST
Commit 8ef8e9839a23 ("rtc: ftrtc010: fix integer overflow in time
calculation") from Aug 27, 2026 (linux-next), leads to the following
Smatch static checker warning:
drivers/rtc/rtc-ftrtc010.c:75 ftrtc010_rtc_read_time()
warn: cast after binop
On Thu, 27 Aug 2026 16:03:20 +0800 Liu Dalin <liudalin@xxxxxxxxxxxxxxx> wrote:
> In ftrtc010_rtc_read_time() and ftrtc010_rtc_set_time(), all
> variables (offset, days, hour, min, sec) are u32. The expression
> "days * 86400 + hour * 3600 + min * 60 + sec" is evaluated in
> 32-bit arithmetic, which silently wraps around for dates beyond
> approximately year 2106 (U32_MAX / 86400 ≈ 49710 days).
>
> In ftrtc010_rtc_read_time(), perform the addition in 32-bit
> arithmetic first to preserve two's complement wrapping for negative
> offsets, then cast the result to timeu64_t. In
> ftrtc010_rtc_set_time(), cast individual u32 operands to timeu64_t
> before multiplication to prevent overflow in the right-hand side
> of the offset calculation.
>
> Fixes: 1d61d2592c1f ("rtc: ftrtc010: Rename to Faraday FTRTC010")
> Assisted-by: Sashiko AI [static analysis]
> Signed-off-by: Liu Dalin <liudalin@xxxxxxxxxxxxxxx>
> ---
> drivers/rtc/rtc-ftrtc010.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
> index 19e6333bfbab..b29c96be40f4 100644
> --- a/drivers/rtc/rtc-ftrtc010.c
> +++ b/drivers/rtc/rtc-ftrtc010.c
> @@ -72,7 +72,7 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
> days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
> offset = readl(rtc->rtc_base + FTRTC010_RTC_RECORD);
>
> - time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
> + time = (timeu64_t)(offset + days * 86400 + hour * 3600 + min * 60 + sec);
There isn't any point in doing the cast outside the parentheses. The
other chunk probably does it correctly.
regards,
dan carpenter
>
> rtc_time64_to_tm(time, tm);
>
> @@ -92,7 +92,8 @@ static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm)
> hour = readl(rtc->rtc_base + FTRTC010_RTC_HOUR);
> day = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
>
> - offset = time - (day * 86400 + hour * 3600 + min * 60 + sec);
> + offset = time - ((timeu64_t)day * 86400 + (timeu64_t)hour * 3600 +
> + (timeu64_t)min * 60 + (timeu64_t)sec);
>
> writel(offset, rtc->rtc_base + FTRTC010_RTC_RECORD);
> writel(0x01, rtc->rtc_base + FTRTC010_RTC_CR);
> --
> 2.43.0
>
>