Skip to content

Commit

Permalink
Handle buffer allocation failure in prvCreateSectors (#1152)
Browse files Browse the repository at this point in the history
* Catch allocation failure in prvCreateSectors

* Fix unit tests

* Fix UTs 2

* Fix formatting
  • Loading branch information
tony-josi-aws authored Jun 17, 2024
1 parent f5cbeb5 commit 0a8ad98
Show file tree
Hide file tree
Showing 16 changed files with 447 additions and 121 deletions.
81 changes: 50 additions & 31 deletions source/FreeRTOS_TCP_State_Handling_IPv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ FreeRTOS_Socket_t * prvHandleListen_IPV4( FreeRTOS_Socket_t * pxSocket,
FreeRTOS_Socket_t * pxReturn = NULL;
uint32_t ulInitialSequenceNumber = 0U;
const NetworkEndPoint_t * pxEndpoint = NULL;
BaseType_t xIsNewSocket = pdFALSE;

if( ( pxSocket != NULL ) && ( pxNetworkBuffer != NULL ) )
{
Expand Down Expand Up @@ -155,6 +156,7 @@ FreeRTOS_Socket_t * prvHandleListen_IPV4( FreeRTOS_Socket_t * pxSocket,
* socket to the new socket. Only the binding might fail (due to
* lack of resources). */
pxReturn = pxNewSocket;
xIsNewSocket = pdTRUE;
}
else
{
Expand All @@ -166,45 +168,62 @@ FreeRTOS_Socket_t * prvHandleListen_IPV4( FreeRTOS_Socket_t * pxSocket,

if( ( ulInitialSequenceNumber != 0U ) && ( pxReturn != NULL ) )
{
size_t xCopyLength;
do
{
size_t xCopyLength;
BaseType_t xReturnCreateWindow;

/* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */
/* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */

/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
const ProtocolHeaders_t * pxProtocolHeaders = ( ( const ProtocolHeaders_t * )
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ) ] ) );
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
const ProtocolHeaders_t * pxProtocolHeaders = ( ( const ProtocolHeaders_t * )
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ) ] ) );

/* The endpoint in network buffer must be valid in this condition. */
pxReturn->pxEndPoint = pxNetworkBuffer->pxEndPoint;
pxReturn->bits.bIsIPv6 = pdFALSE_UNSIGNED;
pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
pxReturn->u.xTCP.xRemoteIP.ulIP_IPv4 = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
/* The endpoint in network buffer must be valid in this condition. */
pxReturn->pxEndPoint = pxNetworkBuffer->pxEndPoint;
pxReturn->bits.bIsIPv6 = pdFALSE_UNSIGNED;
pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
pxReturn->u.xTCP.xRemoteIP.ulIP_IPv4 = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;

/* Here is the SYN action. */
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxProtocolHeaders->xTCPHeader.ulSequenceNumber );
prvSocketSetMSS( pxReturn );
/* Here is the SYN action. */
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxProtocolHeaders->xTCPHeader.ulSequenceNumber );
prvSocketSetMSS( pxReturn );

prvTCPCreateWindow( pxReturn );
xReturnCreateWindow = prvTCPCreateWindow( pxReturn );

vTCPStateChange( pxReturn, eSYN_FIRST );
/* Did allocating TCP sectors fail? */
if( xReturnCreateWindow != pdPASS )
{
/* Close the socket if it was newly created. */
if( xIsNewSocket == pdTRUE )
{
vSocketClose( pxReturn );
}

/* Make a copy of the header up to the TCP header. It is needed later
* on, whenever data must be sent to the peer. */
if( pxNetworkBuffer->xDataLength > sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) )
{
xCopyLength = sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket );
}
else
{
xCopyLength = pxNetworkBuffer->xDataLength;
}
pxReturn = NULL;
break;
}

vTCPStateChange( pxReturn, eSYN_FIRST );

/* Make a copy of the header up to the TCP header. It is needed later
* on, whenever data must be sent to the peer. */
if( pxNetworkBuffer->xDataLength > sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) )
{
xCopyLength = sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket );
}
else
{
xCopyLength = pxNetworkBuffer->xDataLength;
}

( void ) memcpy( ( void * ) pxReturn->u.xTCP.xPacket.u.ucLastPacket,
( const void * ) pxNetworkBuffer->pucEthernetBuffer,
xCopyLength );
( void ) memcpy( ( void * ) pxReturn->u.xTCP.xPacket.u.ucLastPacket,
( const void * ) pxNetworkBuffer->pucEthernetBuffer,
xCopyLength );
} while( ipFALSE_BOOL );
}

return pxReturn;
Expand Down
89 changes: 54 additions & 35 deletions source/FreeRTOS_TCP_State_Handling_IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ FreeRTOS_Socket_t * prvHandleListen_IPV6( FreeRTOS_Socket_t * pxSocket,
FreeRTOS_Socket_t * pxReturn = NULL;
uint32_t ulInitialSequenceNumber = 0;
BaseType_t xHasSequence = pdFALSE;
BaseType_t xIsNewSocket = pdFALSE;

if( ( pxSocket != NULL ) && ( pxNetworkBuffer != NULL ) )
{
Expand Down Expand Up @@ -150,6 +151,7 @@ FreeRTOS_Socket_t * prvHandleListen_IPV6( FreeRTOS_Socket_t * pxSocket,
* socket to the new socket. Only the binding might fail (due to
* lack of resources). */
pxReturn = pxNewSocket;
xIsNewSocket = pdTRUE;
}
else
{
Expand All @@ -161,50 +163,67 @@ FreeRTOS_Socket_t * prvHandleListen_IPV6( FreeRTOS_Socket_t * pxSocket,

if( ( xHasSequence != pdFALSE ) && ( pxReturn != NULL ) )
{
size_t xCopyLength;
const IPHeader_IPv6_t * pxIPHeader_IPv6;
do
{
size_t xCopyLength;
const IPHeader_IPv6_t * pxIPHeader_IPv6;
BaseType_t xReturnCreateWindow;

/* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */
/* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */

/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
const ProtocolHeaders_t * pxProtocolHeaders = ( ( const ProtocolHeaders_t * )
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ) ] ) );
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
const ProtocolHeaders_t * pxProtocolHeaders = ( ( const ProtocolHeaders_t * )
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ) ] ) );

pxReturn->pxEndPoint = pxNetworkBuffer->pxEndPoint;
pxReturn->bits.bIsIPv6 = pdTRUE_UNSIGNED;
pxReturn->pxEndPoint = pxNetworkBuffer->pxEndPoint;
pxReturn->bits.bIsIPv6 = pdTRUE_UNSIGNED;

/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
pxIPHeader_IPv6 = ( ( const IPHeader_IPv6_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
pxReturn->u.xTCP.usRemotePort = FreeRTOS_ntohs( pxTCPPacket->xTCPHeader.usSourcePort );
( void ) memcpy( pxReturn->u.xTCP.xRemoteIP.xIP_IPv6.ucBytes, pxIPHeader_IPv6->xSourceAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
pxIPHeader_IPv6 = ( ( const IPHeader_IPv6_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) );
pxReturn->u.xTCP.usRemotePort = FreeRTOS_ntohs( pxTCPPacket->xTCPHeader.usSourcePort );
( void ) memcpy( pxReturn->u.xTCP.xRemoteIP.xIP_IPv6.ucBytes, pxIPHeader_IPv6->xSourceAddress.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;

/* Here is the SYN action. */
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxProtocolHeaders->xTCPHeader.ulSequenceNumber );
prvSocketSetMSS( pxReturn );
/* Here is the SYN action. */
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxProtocolHeaders->xTCPHeader.ulSequenceNumber );
prvSocketSetMSS( pxReturn );

prvTCPCreateWindow( pxReturn );
xReturnCreateWindow = prvTCPCreateWindow( pxReturn );

vTCPStateChange( pxReturn, eSYN_FIRST );
/* Did allocating TCP sectors fail? */
if( xReturnCreateWindow != pdPASS )
{
/* Close the socket if it was newly created. */
if( xIsNewSocket == pdTRUE )
{
vSocketClose( pxReturn );
}

/* Make a copy of the header up to the TCP header. It is needed later
* on, whenever data must be sent to the peer. */
if( pxNetworkBuffer->xDataLength > sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) )
{
xCopyLength = sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket );
}
else
{
xCopyLength = pxNetworkBuffer->xDataLength;
}
pxReturn = NULL;
break;
}

vTCPStateChange( pxReturn, eSYN_FIRST );

/* Make a copy of the header up to the TCP header. It is needed later
* on, whenever data must be sent to the peer. */
if( pxNetworkBuffer->xDataLength > sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) )
{
xCopyLength = sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket );
}
else
{
xCopyLength = pxNetworkBuffer->xDataLength;
}

( void ) memcpy( ( void * ) pxReturn->u.xTCP.xPacket.u.ucLastPacket,
( const void * ) pxNetworkBuffer->pucEthernetBuffer,
xCopyLength );
( void ) memcpy( ( void * ) pxReturn->u.xTCP.xPacket.u.ucLastPacket,
( const void * ) pxNetworkBuffer->pucEthernetBuffer,
xCopyLength );
} while( ipFALSE_BOOL );
}

return pxReturn;
Expand Down
7 changes: 5 additions & 2 deletions source/FreeRTOS_TCP_Transmission.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,9 @@
* (in FreeRTOS_TCP_WIN.c) needs to know them, along with the Maximum Segment
* Size (MSS).
*/
void prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket )
BaseType_t prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket )
{
BaseType_t xReturn;
uint32_t ulRxWindowSize = ( uint32_t ) pxSocket->u.xTCP.uxRxWinSize;
uint32_t ulTxWindowSize = ( uint32_t ) pxSocket->u.xTCP.uxTxWinSize;

Expand All @@ -466,13 +467,15 @@
( unsigned ) pxSocket->u.xTCP.uxRxStreamSize ) );
}

vTCPWindowCreate(
xReturn = xTCPWindowCreate(
&pxSocket->u.xTCP.xTCPWindow,
ulRxWindowSize * ipconfigTCP_MSS,
ulTxWindowSize * ipconfigTCP_MSS,
pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber,
pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber,
( uint32_t ) pxSocket->u.xTCP.usMSS );

return xReturn;
}
/*-----------------------------------------------------------*/

Expand Down
5 changes: 4 additions & 1 deletion source/FreeRTOS_TCP_Transmission_IPv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,10 @@ BaseType_t prvTCPPrepareConnect_IPV4( FreeRTOS_Socket_t * pxSocket )
/* The initial sequence numbers at our side are known. Later
* vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
* first wait for a SYN+ACK reply. */
prvTCPCreateWindow( pxSocket );
if( prvTCPCreateWindow( pxSocket ) != pdTRUE )
{
xReturn = pdFALSE;
}
}

return xReturn;
Expand Down
5 changes: 4 additions & 1 deletion source/FreeRTOS_TCP_Transmission_IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,10 @@ BaseType_t prvTCPPrepareConnect_IPV6( FreeRTOS_Socket_t * pxSocket )
/* The initial sequence numbers at our side are known. Later
* vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
* first wait for a SYN+ACK reply. */
prvTCPCreateWindow( pxSocket );
if( prvTCPCreateWindow( pxSocket ) != pdTRUE )
{
xReturn = pdFAIL;
}
}
else
{
Expand Down
20 changes: 12 additions & 8 deletions source/FreeRTOS_TCP_WIN.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,20 +777,22 @@
* @param[in] ulSequenceNumber The first sequence number.
* @param[in] ulMSS The MSS of the connection.
*/
void vTCPWindowCreate( TCPWindow_t * pxWindow,
uint32_t ulRxWindowLength,
uint32_t ulTxWindowLength,
uint32_t ulAckNumber,
uint32_t ulSequenceNumber,
uint32_t ulMSS )
BaseType_t xTCPWindowCreate( TCPWindow_t * pxWindow,
uint32_t ulRxWindowLength,
uint32_t ulTxWindowLength,
uint32_t ulAckNumber,
uint32_t ulSequenceNumber,
uint32_t ulMSS )
{
BaseType_t xReturn = pdPASS;

/* Create and initialize a window. */

#if ( ipconfigUSE_TCP_WIN == 1 )
{
if( xTCPSegments == NULL )
{
( void ) prvCreateSectors();
xReturn = prvCreateSectors();
}

vListInitialise( &( pxWindow->xTxSegments ) );
Expand All @@ -804,14 +806,16 @@

if( xTCPWindowLoggingLevel != 0 )
{
FreeRTOS_debug_printf( ( "vTCPWindowCreate: for WinLen = Rx/Tx: %u/%u\n",
FreeRTOS_debug_printf( ( "xTCPWindowCreate: for WinLen = Rx/Tx: %u/%u\n",
( unsigned ) ulRxWindowLength, ( unsigned ) ulTxWindowLength ) );
}

pxWindow->xSize.ulRxWindowLength = ulRxWindowLength;
pxWindow->xSize.ulTxWindowLength = ulTxWindowLength;

vTCPWindowInit( pxWindow, ulAckNumber, ulSequenceNumber, ulMSS );

return xReturn;
}
/*-----------------------------------------------------------*/

Expand Down
2 changes: 1 addition & 1 deletion source/include/FreeRTOS_TCP_Transmission.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ BaseType_t prvTCPPrepareConnect_IPV6( FreeRTOS_Socket_t * pxSocket );
/*
* Initialise the data structures which keep track of the TCP windowing system.
*/
void prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket );
BaseType_t prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket );

/*
* Set the initial properties in the options fields, like the preferred
Expand Down
12 changes: 6 additions & 6 deletions source/include/FreeRTOS_TCP_WIN.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ typedef struct xTCP_WINDOW
*=============================================================================*/

/* Create and initialize a window */
void vTCPWindowCreate( TCPWindow_t * pxWindow,
uint32_t ulRxWindowLength,
uint32_t ulTxWindowLength,
uint32_t ulAckNumber,
uint32_t ulSequenceNumber,
uint32_t ulMSS );
BaseType_t xTCPWindowCreate( TCPWindow_t * pxWindow,
uint32_t ulRxWindowLength,
uint32_t ulTxWindowLength,
uint32_t ulAckNumber,
uint32_t ulSequenceNumber,
uint32_t ulMSS );

/* Destroy a window (always returns NULL)
* It will free some resources: a collection of segments */
Expand Down
Loading

0 comments on commit 0a8ad98

Please sign in to comment.