mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
Guarded _tx_thread_stack_analyze against inverted stack pointers (#727)
Fixes #460 `TX_ULONG_POINTER_DIF` casts the pointer difference to `ULONG`, so when `tx_thread_stack_highest_ptr` sits below `tx_thread_stack_start` the midpoint wraps to a huge value, the probe lands outside the stack, and the search never converges: the caller hangs or faults. `_tx_thread_stack_analyze` now requires the highest pointer to be strictly above the start of the stack, and bounds the final scan by it. #464 covered the `TX_THREAD_STACK_CHECK` path; this covers direct callers too, as @billlamiework suggested on the issue. Inconsistent pointers still mean a real overflow or a corrupted control block, which remains the application's problem. What changes is that ThreadX reports it through the stack error handler instead of hanging. New cases for an inverted and an equal pointer pair crash the suite without the fix and pass with it. Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
@@ -73,6 +73,7 @@ ULONG *stack_ptr;
|
||||
ULONG *stack_lowest;
|
||||
ULONG *stack_highest;
|
||||
ULONG *probe_ptr;
|
||||
ULONG *stack_limit;
|
||||
ULONG probe_count;
|
||||
UINT fill_present;
|
||||
ULONG size;
|
||||
@@ -99,10 +100,16 @@ ULONG size;
|
||||
/* Pickup the highest stack pointer. */
|
||||
stack_highest = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_highest_ptr);
|
||||
|
||||
/* Determine if the pointer is null. */
|
||||
if (stack_highest != TX_NULL)
|
||||
/* Determine if the pointer is null or if the highest stack pointer is not above the
|
||||
start of the stack. The latter indicates a stack overflow or a corrupted thread
|
||||
control block, and the unsigned pointer arithmetic in the binary search below would
|
||||
wrap around and never converge, hanging the caller. */
|
||||
if ((stack_highest != TX_NULL) && (stack_highest > stack_lowest))
|
||||
{
|
||||
|
||||
/* Remember the upper bound of the search so the scan below cannot run past it. */
|
||||
stack_limit = stack_highest;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
@@ -173,7 +180,7 @@ ULONG size;
|
||||
} while(size > ((ULONG) 1));
|
||||
|
||||
/* Position to first used word - at this point we are within a few words. */
|
||||
while (*stack_ptr == TX_STACK_FILL)
|
||||
while ((stack_ptr < stack_limit) && (*stack_ptr == TX_STACK_FILL))
|
||||
{
|
||||
|
||||
/* Position to next word in stack. */
|
||||
|
||||
Reference in New Issue
Block a user