Skip to content

Commit a369c52

Browse files
tony-josi-awstautschnigActoryOukar-rahul-aws
authored
Fix potential out of bounds write (CWE-787) when processing LLMNR or mDNS queries (#1259)
* [Draft] CBMC: replace any missing functions by assert-false (#1147) * CBMC: replace any missing functions by assert-false --------- Co-authored-by: ActoryOu <[email protected]> * Adjust proof tooling to support CBMC v6 (#1180) * Adjust proof tooling to support CBMC v6 With CBMC v6, unwinding assertions as well as other checks are enabled by default. * Fix CBMC issues * Fix spelling & formatting * Fix build-check * Add unit test cases for FreeRTOS_multiply_int32 and FreeRTOS_add_int32 * Tony's comment * Bump CBMC version to very latest release * Replace Synopsys link with blackduck one to solve link error. * Move the comment to the right place --------- Co-authored-by: Tony Josi <[email protected]> Co-authored-by: ActoryOu <[email protected]> Co-authored-by: ActoryOu <[email protected]> * Fix potential out of bounds write (CWE-787) when processing LLMNR or mDNS queries * Fix CI * Add Network Down event in EMACHandler Task (#1173) * Add Network Down event in EMACHandler Task * Update links in ReadMe (#1174) --------- Co-authored-by: Michael Tautschnig <[email protected]> Co-authored-by: ActoryOu <[email protected]> Co-authored-by: ActoryOu <[email protected]> Co-authored-by: Rahul Kar <[email protected]>
1 parent abcb94c commit a369c52

File tree

174 files changed

+2798
-604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+2798
-604
lines changed

.github/.cSpellWords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ BLXNS
8989
bmcr
9090
BMSR
9191
BPDG
92+
BPIALL
9293
brgintclr
9394
brginten
9495
brgintstat
@@ -920,6 +921,7 @@ Picovolts
920921
PIDEVAD
921922
pidr
922923
PIDR
924+
PINSEL
923925
PIOA
924926
PKHBT
925927
pkhtb
@@ -1263,6 +1265,7 @@ STLIDMPUSR
12631265
STLIMPUOR
12641266
STLNVICACTVOR
12651267
STLNVICPENDOR
1268+
Storex
12661269
strbt
12671270
STRBT
12681271
strexb

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ jobs:
128128
path: ./
129129

130130
formatting:
131-
runs-on: ubuntu-20.04
131+
runs-on: ubuntu-latest
132132
steps:
133133
- uses: actions/checkout@v4
134134
- name: Check formatting
@@ -406,7 +406,7 @@ jobs:
406406
- name: Set up CBMC runner
407407
uses: FreeRTOS/CI-CD-Github-Actions/set_up_cbmc_runner@main
408408
with:
409-
cbmc_version: "5.95.1"
409+
cbmc_version: "6.3.1"
410410

411411
- env:
412412
stepName: Install Dependencies

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ This library has undergone static code analysis and checks for compliance with t
55

66
## Getting started
77
The easiest way to use version 4.0.0 and later of FreeRTOS-Plus-TCP is to refer the Getting started Guide (found [here](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/GettingStarted.md))
8-
Another way is to start with the pre-configured IPv4 Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator)) or IPv6 Multi-endpoint Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo)). That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/FreeRTOS-quick-start-guide.html) for detailed instructions and other useful links.
8+
Another way is to start with the pre-configured IPv4 Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator)) or IPv6 Multi-endpoint Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo)). That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/02-Quick-start-guide) for detailed instructions and other useful links.
99

10-
Additionally, for FreeRTOS-Plus-TCP source code organization refer to the [Documentation](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html), and [API Reference](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html).
10+
Additionally, for FreeRTOS-Plus-TCP source code organization refer to the [Documentation](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html), and [API Reference](https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/01-FreeRTOS-plus-TCP-APIs).
1111

1212
### Getting help
13-
If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org). Please also refer to [FAQ](http://www.freertos.org/FAQHelp.html) for frequently asked questions.
13+
If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org). Please also refer to [FAQ](https://www.freertos.org/Why-FreeRTOS/FAQs) for frequently asked questions.
1414

1515
Also see the [Submitting a bugs/feature request](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/.github/CONTRIBUTING.md#submitting-a-bugsfeature-request) section of CONTRIBUTING.md for more details.
1616

@@ -86,7 +86,7 @@ git submodule update --checkout --init --recursive tools/CMock test/FreeRTOS-Ker
8686
```
8787

8888
## Porting
89-
The porting guide is available on [this page](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html).
89+
The porting guide is available on [this page](https://www.freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/01-FreeRTOS_TCP_Porting).
9090

9191
## Repository structure
9292
This repository contains the FreeRTOS-Plus-TCP repository and a number of supplementary libraries for testing/PR Checks.

readme.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A description of the source code organisation is available on:
77
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html
88

99
The porting guide is available on:
10-
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html
10+
https://www.freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/01-FreeRTOS_TCP_Porting
1111

1212
License information is available on:
1313
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_Plus_TCP_License.html

source/FreeRTOS_DHCP.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
/**
8282
* @brief The number of end-points that are making use of the UDP-socket.
8383
*/
84-
static BaseType_t xDHCPSocketUserCount = 0;
84+
_static BaseType_t xDHCPSocketUserCount = 0;
8585

8686
/*
8787
* Generate a DHCP discover message and send it on the DHCP socket.
@@ -881,7 +881,7 @@
881881
configASSERT( xSocketValid( xDHCPv4Socket ) == pdTRUE );
882882

883883
/* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */
884-
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */
884+
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */
885885
/* coverity[misra_c_2012_rule_11_4_violation] */
886886
if( xSocketValid( xDHCPv4Socket ) == pdTRUE )
887887
{

source/FreeRTOS_DHCPv6.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@
8585
( ( ( uint32_t ) 1U ) << DHCPv6_Option_Server_Identifier ) )
8686

8787
/** @brief The UDP socket which is shared by all end-points that need DHCPv6. */
88-
static Socket_t xDHCPv6Socket;
88+
_static Socket_t xDHCPv6Socket;
8989

9090
/** @brief A reference count makes sure that the UDP socket will be deleted when it
9191
* is not used anymore. */
92-
static BaseType_t xDHCPv6SocketUserCount;
92+
_static BaseType_t xDHCPv6SocketUserCount;
9393

9494
static BaseType_t prvIsOptionLengthValid( uint16_t usOption,
9595
size_t uxOptionLength,
@@ -151,7 +151,7 @@ static BaseType_t prvDHCPv6_handleOption( struct xNetworkEndPoint * pxEndPoint,
151151
/**
152152
* @brief DHCP IPv6 message object
153153
*/
154-
static DHCPMessage_IPv6_t xDHCPMessage;
154+
_static DHCPMessage_IPv6_t xDHCPMessage;
155155

156156
/**
157157
* @brief Get the DHCP state from a given endpoint.
@@ -1500,7 +1500,13 @@ static BaseType_t prvDHCPv6Analyse( struct xNetworkEndPoint * pxEndPoint,
15001500
}
15011501
else
15021502
{
1503-
ulOptionsReceived |= ( ( ( uint32_t ) 1U ) << usOption );
1503+
/* ulOptionsReceived has only 32-bits, it's not allowed to shift more than 32-bits on it. */
1504+
if( usOption < 32 )
1505+
{
1506+
/* Store the option by bit-map only if it's less than 32. */
1507+
ulOptionsReceived |= ( ( ( uint32_t ) 1U ) << usOption );
1508+
}
1509+
15041510
xReady = prvDHCPv6_handleOption( pxEndPoint, usOption, &( xSet ), pxDHCPMessage, &( xMessage ) );
15051511
}
15061512

source/FreeRTOS_DNS_Cache.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,9 @@
448448
/* Add or update the item. */
449449
if( strlen( pcName ) < ( size_t ) ipconfigDNS_CACHE_NAME_LENGTH )
450450
{
451-
( void ) strncpy( xDNSCache[ uxFreeEntry ].pcName, pcName, ipconfigDNS_CACHE_NAME_LENGTH );
451+
( void ) strncpy( xDNSCache[ uxFreeEntry ].pcName, pcName, strlen( pcName ) );
452452
( void ) memcpy( &( xDNSCache[ uxFreeEntry ].xAddresses[ 0 ] ), pxIP, sizeof( *pxIP ) );
453453

454-
455454
xDNSCache[ uxFreeEntry ].ulTTL = ulTTL;
456455
xDNSCache[ uxFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
457456
#if ( ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY > 1 )

source/FreeRTOS_DNS_Parser.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -484,31 +484,30 @@
484484
LLMNRAnswer_t * pxAnswer;
485485
uint8_t * pucNewBuffer = NULL;
486486
size_t uxExtraLength;
487+
size_t uxDataLength = uxBufferLength +
488+
sizeof( UDPHeader_t ) +
489+
sizeof( EthernetHeader_t ) +
490+
uxIPHeaderSizePacket( pxNetworkBuffer );
487491

488-
if( xBufferAllocFixedSize == pdFALSE )
489-
{
490-
size_t uxDataLength = uxBufferLength +
491-
sizeof( UDPHeader_t ) +
492-
sizeof( EthernetHeader_t ) +
493-
uxIPHeaderSizePacket( pxNetworkBuffer );
494-
495-
#if ( ipconfigUSE_IPv6 != 0 )
496-
if( xSet.usType == dnsTYPE_AAAA_HOST )
497-
{
498-
uxExtraLength = sizeof( LLMNRAnswer_t ) + ipSIZE_OF_IPv6_ADDRESS - sizeof( pxAnswer->ulIPAddress );
499-
}
500-
else
501-
#endif /* ( ipconfigUSE_IPv6 != 0 ) */
502-
#if ( ipconfigUSE_IPv4 != 0 )
503-
{
504-
uxExtraLength = sizeof( LLMNRAnswer_t );
505-
}
506-
#else /* ( ipconfigUSE_IPv4 != 0 ) */
492+
#if ( ipconfigUSE_IPv6 != 0 )
493+
if( xSet.usType == dnsTYPE_AAAA_HOST )
507494
{
508-
/* do nothing, coverity happy */
495+
uxExtraLength = sizeof( LLMNRAnswer_t ) + ipSIZE_OF_IPv6_ADDRESS - sizeof( pxAnswer->ulIPAddress );
509496
}
510-
#endif /* ( ipconfigUSE_IPv4 != 0 ) */
497+
else
498+
#endif /* ( ipconfigUSE_IPv6 != 0 ) */
499+
#if ( ipconfigUSE_IPv4 != 0 )
500+
{
501+
uxExtraLength = sizeof( LLMNRAnswer_t );
502+
}
503+
#else /* ( ipconfigUSE_IPv4 != 0 ) */
504+
{
505+
/* do nothing, coverity happy */
506+
}
507+
#endif /* ( ipconfigUSE_IPv4 != 0 ) */
511508

509+
if( xBufferAllocFixedSize == pdFALSE )
510+
{
512511
/* Set the size of the outgoing packet. */
513512
pxNetworkBuffer->xDataLength = uxDataLength;
514513
pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer,
@@ -537,7 +536,17 @@
537536
}
538537
else
539538
{
540-
pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ uxUDPOffset ] );
539+
/* When xBufferAllocFixedSize is TRUE, check if the buffer size is big enough to
540+
* store the answer. */
541+
if( ( uxDataLength + uxExtraLength ) <= ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER )
542+
{
543+
pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ uxUDPOffset ] );
544+
}
545+
else
546+
{
547+
/* Just to indicate that the message may not be answered. */
548+
pxNetworkBuffer = NULL;
549+
}
541550
}
542551

543552
if( ( pxNetworkBuffer != NULL ) )
@@ -1093,7 +1102,7 @@
10931102
/* Define the ASCII value of the capital "A". */
10941103
const uint8_t ucCharA = ( uint8_t ) 0x41U;
10951104

1096-
ucByte = ( uint8_t ) ( ( ( pucSource[ 0 ] - ucCharA ) << 4 ) |
1105+
ucByte = ( uint8_t ) ( ( ( ( pucSource[ 0 ] - ucCharA ) & 0x0F ) << 4 ) |
10971106
( pucSource[ 1 ] - ucCharA ) );
10981107

10991108
/* Make sure there are no trailing spaces in the name. */
@@ -1208,7 +1217,11 @@
12081217
{
12091218
/* BufferAllocation_1.c is used, the Network Buffers can contain at least
12101219
* ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER. */
1211-
configASSERT( uxSizeNeeded < ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER );
1220+
if( uxSizeNeeded > ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) )
1221+
{
1222+
/* The buffer is too small to reply. Drop silently. */
1223+
break;
1224+
}
12121225
}
12131226

12141227
pxNetworkBuffer->xDataLength = uxSizeNeeded;

source/FreeRTOS_IP_Utils.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,81 @@ size_t FreeRTOS_min_size_t( size_t a,
16941694
}
16951695
/*-----------------------------------------------------------*/
16961696

1697+
/**
1698+
* @brief Performs a safe addition of two 32-bit integers, preventing overflow and underflow.
1699+
* @param[in] a the first value.
1700+
* @param[in] b the second value.
1701+
* @return The result of a + b if no overflow/underflow occurs, or INT32_MAX/INT32_MIN if overflow/underflow would occur.
1702+
*/
1703+
int32_t FreeRTOS_add_int32( int32_t a,
1704+
int32_t b )
1705+
{
1706+
int32_t ret;
1707+
1708+
if( ( a > 0 ) && ( b > ipINT32_MAX_VALUE - a ) )
1709+
{
1710+
ret = ipINT32_MAX_VALUE; /* Positive overflow */
1711+
}
1712+
else if( ( a < 0 ) && ( b < ipINT32_MIN_VALUE - a ) )
1713+
{
1714+
ret = ipINT32_MIN_VALUE; /* Negative underflow */
1715+
}
1716+
else
1717+
{
1718+
ret = a + b;
1719+
}
1720+
1721+
return ret;
1722+
}
1723+
/*-----------------------------------------------------------*/
1724+
1725+
/**
1726+
* @brief Performs a safe multiplication of two 32-bit integers, preventing overflow and underflow.
1727+
* @param[in] a the first value.
1728+
* @param[in] b the second value.
1729+
* @return The result of a * b if no overflow occurs, or ipINT32_MAX_VALUE if an overflow would occur.
1730+
*/
1731+
int32_t FreeRTOS_multiply_int32( int32_t a,
1732+
int32_t b )
1733+
{
1734+
int32_t ret;
1735+
1736+
/* Check for overflow/underflow */
1737+
if( a > 0 )
1738+
{
1739+
if( ( b > 0 ) && ( a > ipINT32_MAX_VALUE / b ) )
1740+
{
1741+
ret = ipINT32_MAX_VALUE; /* Positive overflow */
1742+
}
1743+
else if( ( b < 0 ) && ( b < ipINT32_MIN_VALUE / a ) )
1744+
{
1745+
ret = ipINT32_MIN_VALUE; /* Negative underflow */
1746+
}
1747+
else
1748+
{
1749+
ret = a * b;
1750+
}
1751+
}
1752+
else
1753+
{
1754+
if( ( b > 0 ) && ( a < ipINT32_MIN_VALUE / b ) )
1755+
{
1756+
ret = ipINT32_MIN_VALUE; /* Negative underflow */
1757+
}
1758+
else if( ( b < 0 ) && ( a < ipINT32_MAX_VALUE / b ) )
1759+
{
1760+
ret = ipINT32_MAX_VALUE; /* Positive overflow */
1761+
}
1762+
else
1763+
{
1764+
ret = a * b;
1765+
}
1766+
}
1767+
1768+
return ret;
1769+
}
1770+
/*-----------------------------------------------------------*/
1771+
16971772
/**
16981773
* @brief Round-up a number to a multiple of 'd'.
16991774
* @param[in] a the first value.

source/FreeRTOS_TCP_Reception.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
size_t uxTCPHeaderOffset = ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer );
100100

101101
/* MISRA Ref 11.3.1 [Misaligned access] */
102-
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
102+
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
103103
/* coverity[misra_c_2012_rule_11_3_violation] */
104104
const ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * )
105105
&( pxNetworkBuffer->pucEthernetBuffer[ uxTCPHeaderOffset ] ) );
@@ -237,7 +237,17 @@
237237
/* Option is only valid in SYN phase. */
238238
if( xHasSYNFlag != 0 )
239239
{
240-
pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ];
240+
/* From RFC7323 - section 2.3, we should limit the WSopt not larger than 14. */
241+
if( pucPtr[ 2 ] > tcpTCP_OPT_WSOPT_MAXIMUM_VALUE )
242+
{
243+
FreeRTOS_debug_printf( ( "The WSopt(%u) from SYN packet is larger than maximum value.", pucPtr[ 2 ] ) );
244+
pxSocket->u.xTCP.ucPeerWinScaleFactor = tcpTCP_OPT_WSOPT_MAXIMUM_VALUE;
245+
}
246+
else
247+
{
248+
pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ];
249+
}
250+
241251
pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
242252
}
243253

@@ -430,7 +440,7 @@
430440
/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */
431441

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

0 commit comments

Comments
 (0)