[RTEMS Project] #4338: rtems_clock_set(): Cannot set future dates later than approximately 2105
RTEMS trac
trac at rtems.org
Fri Mar 12 13:52:51 UTC 2021
#4338: rtems_clock_set(): Cannot set future dates later than approximately 2105
-------------------------+-------------------------------------------------
Reporter: Frank | Owner: Sebastian Huber
Kuehndel |
Type: defect | Status: assigned
Priority: normal | Milestone: 6.1
Component: rtems | Version: 6
Severity: normal | Keywords: rtems_clock_set, 2514,
| _TOD_To_seconds
Blocked By: | Blocking:
-------------------------+-------------------------------------------------
== Short Problem Description ==
[https://docs.rtems.org/branches/master/c-user/clock/directives.html
#rtems-clock-set RTEMS Classic API Guide] says:
> RTEMS can represent time points of this clock in nanoseconds ranging
from 1988-01-01T00:00:00.000000000Z to 2514-05-31T01:53:03.999999999Z.
* Yet, years larger than roughly 2105 to 2110 cannot be set
(or at least the date should be wrong but this never
occured in my tests).
> The possible RETURN VALUES are RTEMS_SUCCESSFUL, RTEMS_INVALID_ADDRESS,
RTEMS_INVALID_CLOCK
* Yet, rtems_clock_set() can return status RTEMS_INVALID_NUMBER, too.
(Only for such dates in the far future.)
== How To Replicate? ==
Call rtems_clock_set() with this time_of-day:
{
year = 2514,
month = 5,
day = 31,
hour = 1,
minute = 53,
second = 3,
ticks = 995
}
The return value will be RTEMS_INVALID_NUMBER.
== Bugs in _TOD_To_seconds() ==
cpukit/rtems/src/clockset.c: rtems_clock_set() calls
* cpukit/rtems/src/clocktodvalidate.c: _TOD_Validate() and
* cpukit/rtems/src/clocktodtoseconds.c: _TOD_To_seconds() and
* cpukit/score/src/coretodset.c: _TOD_Set()
First issue:
_TOD_To_seconds() converts the time_of_day structure into seconds using a
variable `time` of type `uint32_t`. This simply overflows when in comes
close to year 2110.
Debugger output at the end of _TOD_To_seconds():
{{{
(gdb) print the_tod->year
$16 = 2104
(gdb) print time
$17 = 4233686400
}}}
with a higher year:
{{{
(gdb) print the_tod->year
$28 = 2514
(gdb) print *the_tod
$31 = {
year = 2514,
month = 5,
day = 31,
hour = 1,
minute = 53,
second = 3,
ticks = 995
}
(gdb) print time
$29 = 192272
}}}
Second issue:
_TOD_To_seconds() can (most likely) not handle the leap year issues of the
years 2200, 2300, 2400, 2500 because it has dedicated code for the 2100
case only:
{{{
/* The year 2100 is not a leap year */
if ( time
>= (TOD_SECONDS_AT_2100_03_01_00_00 -
TOD_SECONDS_1970_THROUGH_1988)) {
time -= TOD_SECONDS_PER_DAY;
}
}}}
== _TOD_Check_time_of_day_and_run_hooks() causes STATUS_INVALID_NUMBER ==
cpukit/score/src/coretodset.c: _TOD_Set() calls
* cpukit/score/src/coretodset.c:
_TOD_Check_time_of_day_and_run_hooks()
in this code snippet (note `return status`):
{{{
status = _TOD_Check_time_of_day_and_run_hooks( tod );
if ( status != STATUS_SUCCESSFUL ) {
_TOD_Release( lock_context );
return status;
}
}}}
_TOD_Check_time_of_day_and_run_hooks( tod ) can return status
STATUS_INVALID_NUMBER which is not documented for rtems_clock_set(). The
small time in seconds value 192272 from the integer overrun discussed
above triggers the middle `if` clause:
{{{
static Status_Control _TOD_Check_time_of_day_and_run_hooks(
const struct timespec *tod
)
{
if ( !_Watchdog_Is_valid_timespec( tod ) ) {
return STATUS_INVALID_NUMBER;
}
if ( tod->tv_sec < TOD_SECONDS_1970_THROUGH_1988 ) {
return STATUS_INVALID_NUMBER;
}
if ( _Watchdog_Is_far_future_timespec( tod ) ) {
return STATUS_INVALID_NUMBER;
}
return _TOD_Hook_Run( TOD_ACTION_SET_CLOCK, tod );
}
}}}
== Final Notes ==
* I found #2665 and #2548 but I do not say these are relevant here.
* `#define WATCHDOG_MAX_SECONDS 0x3ffffffff` in
cpukit/include/rtems/score/watchdogimpl.h covers 17179869183 seconds which
are some 544 years
* _TOD_Check_time_of_day_and_run_hooks() seems to be only used by
_TOD_Set() but _TOD_Set() has three users.
* I did not check whether the invers conversation (rtems_clock_get_tod())
works for dates which are centuries in the future.
--
Ticket URL: <http://devel.rtems.org/ticket/4338>
RTEMS Project <http://www.rtems.org/>
RTEMS Project
More information about the bugs
mailing list