From 7bbbe4225c92b646faa14e5f5800ed2feba09899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20K=C3=BChndel?= Date: Thu, 8 Apr 2021 15:41:15 +0200 Subject: clock:_TOD_To_seconds(): Fix year 2514 overflow This patch fixes issue #4338 by changing _TOD_Validate() to only accept years till 2105. This requires another patch to change the documentation of rtems_clock_set() and other affected API functions (indicating the end date is 2105 not 2514). I tried to support till year 2514 but it turned out that this needs changing the Timer Manager too. That in turn would mean to change _TOD_Seconds_since_epoch( void ) from 32 to 64 bit. Sebastian pointed out that a naive extension leads to trouble with 32 bit processors. He deemed a safe re-implementation too costly performance wise considering that year 2106 is far away and current binaries using RTEMS Classic API are unlikely to be in use by 2106. The constant TOD_SECONDS_AT_2100_03_01_00_00 in cpukit/rtems/src/clocktodtoseconds.c happens to be wrong by 1 hour. When setting the date 2100-Feb-28 23:59:59 and then reading the date again you will find yourself in 2100-Feb-27. Update #4338 --- cpukit/include/rtems/score/todimpl.h | 16 ++++++++++++++++ cpukit/rtems/src/clocktodtoseconds.c | 2 +- cpukit/rtems/src/clocktodvalidate.c | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'cpukit') diff --git a/cpukit/include/rtems/score/todimpl.h b/cpukit/include/rtems/score/todimpl.h index 9805ec0dfd..316a56ec74 100644 --- a/cpukit/include/rtems/score/todimpl.h +++ b/cpukit/include/rtems/score/todimpl.h @@ -123,6 +123,22 @@ extern "C" { */ #define TOD_BASE_YEAR 1988 +/** + * @brief Latest year to which a time of day can be initialized. + * + * The following constant defines the latest year to which an + * RTEMS time of day can be set using rtems_clock_set(). + * + * 32 bits can accept as latest point in time 2106-Feb-7 6:28:15 + * but to simplify the implementation, is was decided to only + * check that the year is not greater than the year of this constant. + * + * The internal realtime clock can run centuries longer but in + * contrast to the POSIX API, the RTEMS Classic API does not + * support this for efficiency reasons. + */ +#define TOD_LATEST_YEAR 2105 + /** * @addtogroup RTEMSScoreTOD * diff --git a/cpukit/rtems/src/clocktodtoseconds.c b/cpukit/rtems/src/clocktodtoseconds.c index 49ae257243..86e89f86eb 100644 --- a/cpukit/rtems/src/clocktodtoseconds.c +++ b/cpukit/rtems/src/clocktodtoseconds.c @@ -23,7 +23,7 @@ #include #include -#define TOD_SECONDS_AT_2100_03_01_00_00 4107538800UL +#define TOD_SECONDS_AT_2100_03_01_00_00 4107542400UL /* * The following array contains the number of days in all months diff --git a/cpukit/rtems/src/clocktodvalidate.c b/cpukit/rtems/src/clocktodvalidate.c index d8af275d04..2685bfd6e7 100644 --- a/cpukit/rtems/src/clocktodvalidate.c +++ b/cpukit/rtems/src/clocktodvalidate.c @@ -52,6 +52,7 @@ bool _TOD_Validate( (the_tod->month == 0) || (the_tod->month > TOD_MONTHS_PER_YEAR) || (the_tod->year < TOD_BASE_YEAR) || + (the_tod->year > TOD_LATEST_YEAR) || (the_tod->day == 0) ) return false; -- cgit v1.2.3