diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 243edd37c0d7..1e863f1d36fd 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -30,6 +30,27 @@ config RTC_HCTOSYS the value read from a specified RTC device. This is useful to avoid unnecessary fsck runs at boot time, and to network better. +config RTC_HCTOSYS_TIME32_LIMIT + bool "Reject RTC dates after the 2038 cutoff" + depends on RTC_HCTOSYS && COMPAT_32BIT_TIME && !64BIT + default y + help + Reject RTC dates after 03:14:07 UTC on 19 January 2038 when + initializing the system clock in order to work around broken + RTC implementations that produce nondeterministic timestamps + without a working backup battery. + + A rejected date leaves system time unchanged, normally near + the Unix epoch, and the RTC's hctosys sysfs attribute reads + 0. Userspace must supply the time if no other source has + initialized it. + + Say Y here if the kernel may have to run old time32 userspace on + hardware that can produce unpredictable RTC timestamps. If the + kernel is intended to only run time64 compatible userspace and + continue working past 2038, you must pick N here in order to + have a working RTC_HCTOSYS functionality. + config RTC_HCTOSYS_DEVICE string "RTC used to set the system time" depends on RTC_HCTOSYS diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 01ba04028f1f..18ea141ab8c2 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -72,12 +72,14 @@ static void rtc_hctosys(struct rtc_device *rtc) tv64.tv_sec = rtc_tm_to_time64(&tm); -#if BITS_PER_LONG == 32 - if (tv64.tv_sec > INT_MAX) { + if (IS_ENABLED(CONFIG_RTC_HCTOSYS_TIME32_LIMIT) && + tv64.tv_sec > INT_MAX) { + dev_warn(rtc->dev.parent, + "hctosys: rejecting %ptR UTC due to CONFIG_RTC_HCTOSYS_TIME32_LIMIT=y\n", + &tm); err = -ERANGE; goto err_read; } -#endif err = do_settimeofday64(&tv64);