From 90c52423be9933d5e85c20c6a0266b2c565f030a Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 24 Apr 2022 11:34:56 +0200 Subject: [PATCH] lib/date: Make rtc_mktime and mktime64 Y2038-ready We currently overflow due to wrong types used internally in rtc_mktime, on all platforms, and we return a too small type on 32-bit. One consumer that directly benefits from this is mktime64. Many others may still store the result in a wrong type. While at it, drop the redundant cast of mon in rtc_mktime (obsoleted by 714209832db1). Signed-off-by: Jan Kiszka --- include/linux/time.h | 3 --- include/rtc.h | 8 +++++--- lib/date.c | 13 +++++-------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/linux/time.h b/include/linux/time.h index 702dd276ae..14ff5b6f48 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -152,9 +152,6 @@ _DEFUN (ctime_r, (tim_p, result), return asctime_r (localtime_r (tim_p, &tm), result); } -/* for compatibility with linux code */ -typedef __s64 time64_t; - #ifdef CONFIG_LIB_DATE time64_t mktime64(const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, diff --git a/include/rtc.h b/include/rtc.h index 6c7fcadd48..10104e3bf5 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -16,6 +16,8 @@ #include #include +typedef int64_t time64_t; + #ifdef CONFIG_DM_RTC struct udevice; @@ -301,7 +303,7 @@ int rtc_calc_weekday(struct rtc_time *time); void rtc_to_tm(u64 time_t, struct rtc_time *time); /** - * rtc_mktime() - Convert a broken-out time into a time_t value + * rtc_mktime() - Convert a broken-out time into a time64_t value * * The following fields need to be valid for this function to work: * tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year @@ -309,9 +311,9 @@ void rtc_to_tm(u64 time_t, struct rtc_time *time); * Note that tm_wday and tm_yday are ignored. * * @time: Broken-out time to convert - * Return: corresponding time_t value, seconds since 1970-01-01 00:00:00 + * Return: corresponding time64_t value, seconds since 1970-01-01 00:00:00 */ -unsigned long rtc_mktime(const struct rtc_time *time); +time64_t rtc_mktime(const struct rtc_time *time); /** * rtc_month_days() - The number of days in the month diff --git a/lib/date.c b/lib/date.c index c589d9ed3a..e3d22459cd 100644 --- a/lib/date.c +++ b/lib/date.c @@ -71,19 +71,16 @@ int rtc_calc_weekday(struct rtc_time *tm) * -year / 100 + year / 400 terms, and add 10.] * * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines where long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) */ -unsigned long rtc_mktime(const struct rtc_time *tm) +time64_t rtc_mktime(const struct rtc_time *tm) { int mon = tm->tm_mon; int year = tm->tm_year; - int days, hours; + unsigned long days; + time64_t hours; mon -= 2; - if (0 >= (int)mon) { /* 1..12 -> 11, 12, 1..10 */ + if (0 >= mon) { /* 1..12 -> 11, 12, 1..10 */ mon += 12; /* Puts Feb last since it has leap day */ year -= 1; } @@ -109,5 +106,5 @@ time64_t mktime64(const unsigned int year, const unsigned int mon, time.tm_min = min; time.tm_sec = sec; - return (time64_t)rtc_mktime((const struct rtc_time *)&time); + return rtc_mktime((const struct rtc_time *)&time); }