Skip to content

Commit cb54117

Browse files
committed
Fix integer wrap around with IPv6 payload length field processing
1 parent 4f4adb3 commit cb54117

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

source/FreeRTOS_IPv6_Utils.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ BaseType_t prvChecksumIPv6Checks( uint8_t * pucEthernetBuffer,
9292
{
9393
uxExtensionHeaderLength = usGetExtensionHeaderLength( pucEthernetBuffer, uxBufferLength, &pxSet->ucProtocol );
9494

95-
if( uxExtensionHeaderLength >= uxBufferLength )
95+
if( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtensionHeaderLength >= uxBufferLength )
9696
{
9797
/* Error detected when parsing extension header. */
9898
pxSet->usChecksum = ipINVALID_LENGTH;
@@ -108,7 +108,16 @@ BaseType_t prvChecksumIPv6Checks( uint8_t * pucEthernetBuffer,
108108
pxSet->pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtensionHeaderLength ] ) );
109109
pxSet->usPayloadLength = FreeRTOS_ntohs( pxSet->pxIPPacket_IPv6->usPayloadLength );
110110
/* For IPv6, the number of bytes in the protocol is indicated. */
111-
pxSet->usProtocolBytes = ( uint16_t ) ( pxSet->usPayloadLength - uxExtensionHeaderLength );
111+
if( pxSet->usPayloadLength < uxExtensionHeaderLength )
112+
{
113+
/* Invalid payload length - extension headers exceed payload. */
114+
pxSet->usChecksum = ipINVALID_LENGTH;
115+
xReturn = 4;
116+
}
117+
else
118+
{
119+
pxSet->usProtocolBytes = ( uint16_t ) ( pxSet->usPayloadLength - uxExtensionHeaderLength );
120+
}
112121

113122
uxNeeded = ( size_t ) pxSet->usPayloadLength;
114123
uxNeeded += ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER;

test/cbmc/proofs/prvChecksumIPv6Checks/prvChecksumIPv6Checks_harness.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,27 @@ void harness()
2121
size_t uxBufferSize;
2222
uint8_t * pucEthernetBuffer;
2323
struct xPacketSummary xSet;
24+
BaseType_t xReturn;
2425

2526
/* We must have ethernet header to get frame type. */
2627
__CPROVER_assume( uxBufferSize >= sizeof( IPPacket_IPv6_t ) && uxBufferSize <= ipconfigNETWORK_MTU );
2728

2829
/* Ethernet buffer is not possible to be NULL. */
2930
pucEthernetBuffer = ( uint8_t * ) safeMalloc( uxBufferSize );
3031
__CPROVER_assume( pucEthernetBuffer != NULL );
32+
__CPROVER_havoc_object( pucEthernetBuffer );
3133

3234
/* This is set before calling prvChecksumIPv6Checks. */
3335
xSet.pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
3436
xSet.pxIPPacket_IPv6 = ( const IPHeader_IPv6_t * ) ( pucEthernetBuffer + ipSIZE_OF_ETH_HEADER );
3537

36-
prvChecksumIPv6Checks( pucEthernetBuffer,
38+
xReturn = prvChecksumIPv6Checks( pucEthernetBuffer,
3739
uxBufferSize,
3840
&xSet );
41+
42+
if( xReturn == 0 )
43+
{
44+
__CPROVER_assert( ( xSet.usProtocolBytes <= FreeRTOS_ntohs( xSet.pxIPPacket_IPv6->usPayloadLength ) ), "xSet.usProtocolBytes shouldn't be greater than IPv6 usPayloadLength" );
45+
}
46+
3947
}

0 commit comments

Comments
 (0)