From 54b4b1f85af465acb4627ec423599a6c3b4a6fad Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 3 Sep 2021 09:46:36 +0200 Subject: score: Add _TOD_Is_valid_new_time_of_day() Move the TOD validation to the callers of _TOD_Set(). This avoids dead code in case only rtems_clock_set() is used in an application because rtems_clock_set() always calls _TOD_Set() with a valid time of day. --- cpukit/Makefile.am | 1 + cpukit/include/rtems/score/todimpl.h | 14 ++++++++- cpukit/posix/src/clocksettime.c | 5 +++ cpukit/score/src/coretodadjust.c | 7 ++++- cpukit/score/src/coretodcheck.c | 59 ++++++++++++++++++++++++++++++++++++ cpukit/score/src/coretodset.c | 22 ++------------ spec/build/cpukit/librtemscpu.yml | 1 + 7 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 cpukit/score/src/coretodcheck.c diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index 6b2c1fb5b7..591065adf3 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -1006,6 +1006,7 @@ librtemscpu_a_SOURCES += score/src/timespecgetasnanoseconds.c librtemscpu_a_SOURCES += score/src/coretod.c librtemscpu_a_SOURCES += score/src/coretodset.c librtemscpu_a_SOURCES += score/src/coretodadjust.c +librtemscpu_a_SOURCES += score/src/coretodcheck.c librtemscpu_a_SOURCES += score/src/watchdoginsert.c librtemscpu_a_SOURCES += score/src/coretodhookdata.c librtemscpu_a_SOURCES += score/src/coretodhookregister.c diff --git a/cpukit/include/rtems/score/todimpl.h b/cpukit/include/rtems/score/todimpl.h index 5346f12e53..ceeef2e21b 100644 --- a/cpukit/include/rtems/score/todimpl.h +++ b/cpukit/include/rtems/score/todimpl.h @@ -206,13 +206,25 @@ static inline void _TOD_Release( ISR_lock_Context *lock_context ) _Timecounter_Release( lock_context ); } +/** + * @brief Checks the time point is a valid new time of day for _TOD_Set(). + * + * @param tod the time of day to check. + * + * @retval STATUS_SUCCESSFUL The time of day is valid. + * + * @retval STATUS_INVALID_NUMBER The time of day is invalid. + */ +Status_Control _TOD_Is_valid_new_time_of_day( const struct timespec *tod ); + /** * @brief Sets the time of day. * * The caller must be the owner of the TOD lock. * * @param tod The new time of day in timespec format representing - * the time since UNIX Epoch. + * the time since UNIX Epoch. The new time of day shall be valid according + * to _TOD_Is_valid_new_time_of_day(). * @param lock_context The ISR lock context used for the corresponding * _TOD_Acquire(). The caller must be the owner of the TOD lock. This * function will release the TOD lock. diff --git a/cpukit/posix/src/clocksettime.c b/cpukit/posix/src/clocksettime.c index 53e728762e..23bb14a86d 100644 --- a/cpukit/posix/src/clocksettime.c +++ b/cpukit/posix/src/clocksettime.c @@ -41,6 +41,11 @@ int clock_settime( if ( clock_id == CLOCK_REALTIME ) { ISR_lock_Context lock_context; + status = _TOD_Is_valid_new_time_of_day( tp ); + if ( status != STATUS_SUCCESSFUL ) { + rtems_set_errno_and_return_minus_one( STATUS_GET_POSIX( status ) ); + } + _TOD_Lock(); _TOD_Acquire( &lock_context ); status = _TOD_Set( tp, &lock_context ); diff --git a/cpukit/score/src/coretodadjust.c b/cpukit/score/src/coretodadjust.c index 90c99803e1..b048aeee71 100644 --- a/cpukit/score/src/coretodadjust.c +++ b/cpukit/score/src/coretodadjust.c @@ -42,7 +42,12 @@ Status_Control _TOD_Adjust( _TOD_Acquire( &lock_context ); _TOD_Get( &tod ); _Timespec_Add_to( &tod, delta ); - status = _TOD_Set( &tod, &lock_context ); + status = _TOD_Is_valid_new_time_of_day( &tod ); + + if ( status == STATUS_SUCCESSFUL ) { + status = _TOD_Set( &tod, &lock_context ); + } + _TOD_Unlock(); return status; diff --git a/cpukit/score/src/coretodcheck.c b/cpukit/score/src/coretodcheck.c new file mode 100644 index 0000000000..b42435aa43 --- /dev/null +++ b/cpukit/score/src/coretodcheck.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSScoreTOD + * + * @brief This source file contains the implementation of + * _TOD_Is_valid_new_time_of_day(). + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +Status_Control _TOD_Is_valid_new_time_of_day( 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 STATUS_SUCCESSFUL; +} diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c index 5fc01215e0..b04242a0da 100644 --- a/cpukit/score/src/coretodset.c +++ b/cpukit/score/src/coretodset.c @@ -23,25 +23,6 @@ #include #include -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 ); -} - Status_Control _TOD_Set( const struct timespec *tod, ISR_lock_Context *lock_context @@ -54,8 +35,9 @@ Status_Control _TOD_Set( Status_Control status; _Assert( _TOD_Is_owner() ); + _Assert( _TOD_Is_valid_new_time_of_day( tod ) == STATUS_SUCCESSFUL ); - status = _TOD_Check_time_of_day_and_run_hooks( tod ); + status = _TOD_Hook_Run( TOD_ACTION_SET_CLOCK, tod ); if ( status != STATUS_SUCCESSFUL ) { _TOD_Release( lock_context ); return status; diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 5957661bd7..16092df2cb 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1390,6 +1390,7 @@ source: - cpukit/score/src/coresem.c - cpukit/score/src/coretod.c - cpukit/score/src/coretodadjust.c +- cpukit/score/src/coretodcheck.c - cpukit/score/src/coretodhookdata.c - cpukit/score/src/coretodhookregister.c - cpukit/score/src/coretodhookrun.c -- cgit v1.2.3