From f81893bd972ea3987f8860541ac2c74724bb055e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 23 Mar 2015 16:14:19 +0000 Subject: [PATCH] Added experimental system integrity check API chSysIntegrityCheckI(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7799 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/rt/include/chsys.h | 11 +++++ os/rt/src/chsys.c | 112 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/os/rt/include/chsys.h b/os/rt/include/chsys.h index 7cc6aca5c..888e98b5c 100644 --- a/os/rt/include/chsys.h +++ b/os/rt/include/chsys.h @@ -34,6 +34,16 @@ /* Module constants. */ /*===========================================================================*/ +/** + * @name Masks of executable integrity checks. + * @{ + */ +#define CH_INTEGRITY_RLIST 1 +#define CH_INTEGRITY_VTLIST 2 +#define CH_INTEGRITY_REGISTRY 4 +#define CH_INTEGRITY_PORT 8 +/** @} */ + /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ @@ -230,6 +240,7 @@ extern "C" { #endif void chSysInit(void); void chSysHalt(const char *reason); + bool chSysIntegrityCheckI(unsigned testmask); void chSysTimerHandlerI(void); syssts_t chSysGetStatusAndLockX(void); void chSysRestoreStatusX(syssts_t sts); diff --git a/os/rt/src/chsys.c b/os/rt/src/chsys.c index fad84179e..5a9e38cf9 100644 --- a/os/rt/src/chsys.c +++ b/os/rt/src/chsys.c @@ -171,6 +171,118 @@ void chSysHalt(const char *reason) { } } +/** + * @brief System integrity check. + * @details Performs an integrity check of the important ChibiOS/RT data + * structures. + * @note The appropriate action in case of failure is to halt the system + * before releasing the critical zone. + * @note If the system is corrupted then one possible outcome of this + * function is an exception caused by @p NULL or corrupted pointers + * in list elements. Exception vectors must be monitored as well. + * @note This function is not used internally, it is up to the + * application to define if and where to perform system + * checking. + * @note Performing all tests at once can be a slow operation and can + * degrade the system response time. It is suggested to execute + * one test at time and release the critical zone in between tests. + * + * @param[in] testmask Each bit in this mask is associated to a test to be + * performed. + * @return The test result. + * @retval false The test succeeded. + * @retval true Test failed. + * + * @iclass + */ +bool chSysIntegrityCheckI(unsigned testmask) { + cnt_t n; + + /* Ready List integrity check.*/ + if ((testmask & CH_INTEGRITY_RLIST) != 0U) { + thread_t *tp; + + /* Scanning the ready list forward.*/ + n = 0; + tp = ch.rlist.r_queue.p_next; + while (tp != (thread_t *)&ch.rlist.r_queue) { + n++; + tp = tp->p_next; + } + + /* Scanning the ready list backward.*/ + tp = ch.rlist.r_queue.p_prev; + while (tp != (thread_t *)&ch.rlist.r_queue) { + n--; + tp = tp->p_prev; + } + + /* The number of elements must match.*/ + if (n != 0) { + return true; + } + } + + /* Timers list integrity check.*/ + if ((testmask & CH_INTEGRITY_VTLIST) != 0U) { + virtual_timer_t * vtp; + + /* Scanning the timers list forward.*/ + n = 0; + vtp = ch.vtlist.vt_next; + while (vtp != (virtual_timer_t *)&ch.vtlist) { + n++; + vtp = vtp->vt_next; + } + + /* Scanning the timers list backward.*/ + vtp = ch.vtlist.vt_prev; + while (vtp != (virtual_timer_t *)&ch.vtlist) { + n--; + vtp = vtp->vt_prev; + } + + /* The number of elements must match.*/ + if (n != 0) { + return true; + } + } + +#if CH_CFG_USE_REGISTRY == TRUE + if ((testmask & CH_INTEGRITY_REGISTRY) != 0U) { + thread_t *tp; + + /* Scanning the ready list forward.*/ + n = 0; + tp = ch.rlist.r_newer; + while (tp != (thread_t *)&ch.rlist) { + n++; + tp = tp->p_newer; + } + + /* Scanning the ready list backward.*/ + tp = ch.rlist.r_older; + while (tp != (thread_t *)&ch.rlist) { + n--; + tp = tp->p_older; + } + + /* The number of elements must match.*/ + if (n != 0) { + return true; + } + } +#endif /* CH_CFG_USE_REGISTRY == TRUE */ + +#if defined(PORT_INTEGRITY_CHECK) + if ((testmask & CH_INTEGRITY_PORT) != 0U) { + PORT_INTEGRITY_CHECK(); + } +#endif + + return false; +} + /** * @brief Handles time ticks for round robin preemption and timer increments. * @details Decrements the remaining time quantum of the running thread