Skip to content

Commit 5b83e82

Browse files
committed
fix(ESPCS-924): Fixed a potential freertos crash
- Reason: A task and B interrupt indirectly access the shared resource pxDelayedTaskList without proper security protection, leading to further crash. A task uses xEventGroupSetBits() to access the pxDelayedTaskList resource: xEventGroupSetBits() -> vTaskRemoveFromUnorderedEventList() -> uxListRemove() -> pxList, where pxList is the pxDelayedTaskList. At this point, another B interrupt is triggered (xEventGroupSetBits only suspends task scheduling and does not disable interrupts) and also accesses the pxDelayedTaskList resource: MacIsrSigPostDefHdl() -> __wifi_queue_send_from_isr() -> xQueueGenericSendFromISR() -> xTaskRemoveFromEventList() -> prvResetNextTaskUnblockTime() -> pxDelayedTaskList. This leads to an unsafe access to the pxDelayedTaskList resource by two entities, causing subsequent crash exceptions. - Fix: Modify the timing of the call to prvResetNextTaskUnblockTime() within xTaskRemoveFromEventList from unconditional execution to only execute when task scheduling is enabled. This way, when the B interrupt reaches xTaskRemoveFromEventList, it will not call prvResetNextTaskUnblockTime to access the pxDelayedTaskList resource (due to task scheduling being disabled). After the B interrupt execution is complete and control returns to A task, xTaskResumeAll() will be called, and then prvResetNextTaskUnblockTime() will update the pxDelayedTaskList resource again.
1 parent 015f309 commit 5b83e82

File tree

1 file changed

+13
-14
lines changed
  • components/freertos/freertos

1 file changed

+13
-14
lines changed

components/freertos/freertos/tasks.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,6 +3044,19 @@ BaseType_t xReturn;
30443044
{
30453045
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
30463046
prvAddTaskToReadyList( pxUnblockedTCB );
3047+
#if( configUSE_TICKLESS_IDLE != 0 )
3048+
{
3049+
/* If a task is blocked on a kernel object then xNextTaskUnblockTime
3050+
might be set to the blocked task's time out time. If the task is
3051+
unblocked for a reason other than a timeout xNextTaskUnblockTime is
3052+
normally left unchanged, because it is automatically reset to a new
3053+
value when the tick count equals xNextTaskUnblockTime. However if
3054+
tickless idling is used it might be more important to enter sleep mode
3055+
at the earliest possible time - so reset xNextTaskUnblockTime here to
3056+
ensure it is updated at the earliest possible time. */
3057+
prvResetNextTaskUnblockTime();
3058+
}
3059+
#endif
30473060
}
30483061
else
30493062
{
@@ -3068,20 +3081,6 @@ BaseType_t xReturn;
30683081
xReturn = pdFALSE;
30693082
}
30703083

3071-
#if( configUSE_TICKLESS_IDLE != 0 )
3072-
{
3073-
/* If a task is blocked on a kernel object then xNextTaskUnblockTime
3074-
might be set to the blocked task's time out time. If the task is
3075-
unblocked for a reason other than a timeout xNextTaskUnblockTime is
3076-
normally left unchanged, because it is automatically reset to a new
3077-
value when the tick count equals xNextTaskUnblockTime. However if
3078-
tickless idling is used it might be more important to enter sleep mode
3079-
at the earliest possible time - so reset xNextTaskUnblockTime here to
3080-
ensure it is updated at the earliest possible time. */
3081-
prvResetNextTaskUnblockTime();
3082-
}
3083-
#endif
3084-
30853084
return xReturn;
30863085
}
30873086
/*-----------------------------------------------------------*/

0 commit comments

Comments
 (0)