mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-10-09 23:53:04 -04:00
fix(POSIX port): check pthread_key_create/pthread_setspecific return values
prvInitThreadKey() ignored pthread_key_create()'s return value, and prvMarkAsFreeRTOSThread() ignored pthread_setspecific()'s return value. If pthread_setspecific() fails, the one-byte thread marker allocated just before it is neither stored in TLS (so prvThreadKeyDestructor() never runs for it, leaking the allocation) nor freed locally -- and the thread is left unmarked, so prvIsFreeRTOSThread() silently misclassifies it as not a FreeRTOS thread. The correctness impact (thread identity) is larger than the one-byte leak itself. Fix: check both return values. On pthread_setspecific() failure, free the marker to avoid the leak, then call prvFatalError() -- the same handling this port already uses for other unexpected pthread call failures (pthread_create(), sigaction()). This function returns void, so there is no way to propagate a failure to the caller; continuing past a failed pthread_setspecific() would leave the thread silently misclassified rather than failing loudly. Same treatment for pthread_key_create(), since a failure there means every later pthread_setspecific()/pthread_getspecific() call on xThreadKey is operating on an invalid key. Fixes #1447 Signed-off-by: Saikumar Mandaji <mandajisaikumar@gmail.com>
This commit is contained in:
parent
78069a79ea
commit
ccbd282d5c
1 changed files with 25 additions and 2 deletions
27
portable/ThirdParty/GCC/Posix/port.c
vendored
27
portable/ThirdParty/GCC/Posix/port.c
vendored
|
|
@ -139,7 +139,15 @@ static void prvThreadKeyDestructor( void * pvData )
|
|||
|
||||
static void prvInitThreadKey( void )
|
||||
{
|
||||
pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
|
||||
int iRet;
|
||||
|
||||
iRet = pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
|
||||
|
||||
if( iRet != 0 )
|
||||
{
|
||||
prvFatalError( "pthread_key_create", iRet );
|
||||
}
|
||||
|
||||
/* Destroy xThreadKey when the process exits. */
|
||||
atexit( prvDestroyThreadKey );
|
||||
}
|
||||
|
|
@ -148,6 +156,7 @@ static void prvInitThreadKey( void )
|
|||
static void prvMarkAsFreeRTOSThread( void )
|
||||
{
|
||||
uint8_t * pucThreadData = NULL;
|
||||
int iRet;
|
||||
|
||||
( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey );
|
||||
|
||||
|
|
@ -156,7 +165,21 @@ static void prvMarkAsFreeRTOSThread( void )
|
|||
|
||||
*pucThreadData = 1;
|
||||
|
||||
pthread_setspecific( xThreadKey, pucThreadData );
|
||||
iRet = pthread_setspecific( xThreadKey, pucThreadData );
|
||||
|
||||
if( iRet != 0 )
|
||||
{
|
||||
/* The marker was not stored, so the TLS destructor would never run
|
||||
* for it -- free it here instead of leaking it, then treat the
|
||||
* failure as fatal via prvFatalError(), consistent with how this
|
||||
* port already handles other unexpected pthread call failures
|
||||
* (see pthread_create()/sigaction() above). This function returns
|
||||
* void, so there is no way to propagate the failure to the caller;
|
||||
* continuing would leave the thread unmarked and silently
|
||||
* misclassified by prvIsFreeRTOSThread(). */
|
||||
free( pucThreadData );
|
||||
prvFatalError( "pthread_setspecific", iRet );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue