mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
rtc: ftrtc010: fix integer overflow in time calculation
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: 1d61d2592c ("rtc: gemini/ftrtc010: rename driver and symbols")
Assisted-by: Sashiko AI [static analysis]
Signed-off-by: Liu Dalin <liudalin@kylinsec.com.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Tested-by: Liu Dalin <liudalin@kylinsec.com.cn>
Link: https://patch.msgid.link/42C8FBD59AA34EA9+20260827080320.3351155-4-liudalin@kylinsec.com.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
d41ee317c9
commit
32f04694fa
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user