From e3f6d35f65a49a2e5f79ddba0645bb9b7e51f182 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 2 Jan 2020 15:45:30 -0700 Subject: cpukit/score: avoid NULL and races in priority mutex The PIP modifications from #3359 introduced new data structures to track priority inheritance. Prioritized mutexes without PIP share some of the code paths, and may result in NULL pointer accesses. This patch checks for NULL, and also adds ISR critical sections to an uncovered corner case during thread restarts. Closes #3829. --- cpukit/score/src/threadqextractpriority.c | 4 +++- cpukit/score/src/threadreset.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cpukit/score/src/threadqextractpriority.c b/cpukit/score/src/threadqextractpriority.c index 5c8188d661..9288d17980 100644 --- a/cpukit/score/src/threadqextractpriority.c +++ b/cpukit/score/src/threadqextractpriority.c @@ -109,7 +109,9 @@ bool _Thread_queue_Extract_priority_helper( } mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node ); - _Thread_Evaluate_priority( mutex->holder ); + if ( mutex != NULL ) { + _Thread_Evaluate_priority( mutex->holder ); + } if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { _ISR_Enable( level ); diff --git a/cpukit/score/src/threadreset.c b/cpukit/score/src/threadreset.c index 464a611391..6a03135af1 100644 --- a/cpukit/score/src/threadreset.c +++ b/cpukit/score/src/threadreset.c @@ -48,6 +48,7 @@ void _Thread_Reset( ) { CORE_mutex_Control *mutex; + ISR_Level level; the_thread->resource_count = 0; #if defined(RTEMS_ITRON_API) @@ -66,18 +67,23 @@ void _Thread_Reset( (void) _Watchdog_Remove( &the_thread->Timer ); } + _ISR_Disable( level ); if ( the_thread->Priority_node.waiting_to_hold != NULL ) { mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node ); _Thread_Evaluate_priority( mutex->holder ); } + _ISR_Enable( level ); + _ISR_Disable( level ); while ( !_Chain_Is_empty( &the_thread->Priority_node.Inherited_priorities ) ) { _Thread_Dequeue_priority_node( ((Thread_Priority_node*)_Chain_First( &the_thread->Priority_node.Inherited_priorities )) ); + _ISR_Flash( level ); } + _ISR_Enable( level ); if ( the_thread->Priority_node.current_priority != the_thread->Start.initial_priority ) { the_thread->Priority_node.real_priority = the_thread->Start.initial_priority; -- cgit v1.2.3