Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
description: 'Release Version Number (Eg, v1.0.0-rc1)'
required: true

# Workflow permissions block
permissions:
contents: write # This grants write access to repository content, including pushing commits/tags and creating releases.

jobs:
tag-commit:
name: Tag commit
Expand All @@ -32,4 +36,4 @@ jobs:
git tag -d ${{ github.event.inputs.version_number }}
git remote update
git checkout tags/${{ github.event.inputs.version_number }}
git diff ${{ github.event.inputs.commit_id }} tags/${{ github.event.inputs.version_number }}
git diff ${{ github.event.inputs.commit_id }} tags/${{ github.event.inputs.version_number }}
12 changes: 12 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
description: 'Release Version Number (Eg, v1.0.0)'
required: true

# Workflow permissions block
permissions:
contents: write # This grants write access to repository content, including pushing commits/tags and creating releases.

jobs:
tag-commit:
name: Tag commit
Expand Down Expand Up @@ -140,6 +144,9 @@ jobs:
ref: ${{ github.event.inputs.version_number }}
add_release: "true"
create-release:
permissions:
contents: write
id-token: write
needs:
- create-zip
- deploy-doxygen
Expand Down Expand Up @@ -171,6 +178,11 @@ jobs:
asset_path: ./FreeRTOS-Plus-TCP-${{ github.event.inputs.version_number }}.zip
asset_name: FreeRTOS-Plus-TCP-${{ github.event.inputs.version_number }}.zip
asset_content_type: application/zip
- name: Backup Release Asset
uses: FreeRTOS/CI-CD-Github-Actions/artifact-backup@main
with:
artifact_path: ./FreeRTOS-Plus-TCP-${{ github.event.inputs.version_number }}.zip
release_tag: ${{ github.event.inputs.version_number }}
cleanup:
needs:
- create-release
Expand Down
25 changes: 25 additions & 0 deletions History.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
Documentation and download available at https://www.FreeRTOS.org/

Changes between FreeRTOS-plus-TCP V4.3.4 and V4.3.3 released October 10, 2025:
+ The implementation lacked sufficient checks to ensure that received packets
meet the minimum size requirements for certain ICMPv6 message types, leading to
out-of-bounds read operations when processing packets smaller than the expected
size. This issue has been fixed by adding checks to prevent out-of-bounds reads.
The implementation lacked sufficient checks to prevent null pointer dereference
when an IPv6 multicast packet is received on a device not configured with a
link-local endpoint. This issue has been fixed by adding checks to prevent
null pointer dereference.
+ The implementation lacked sufficient checks to validate the payload length field
in the IPv6 packet header. This allowed malicious packets with incorrect payload
lengths to cause integer wraparound, resulting in erroneously large calculated
payload length. This inflated payload length bypassed the existing
bounds-checking mechanisms, leading to out-of-bounds read operations. This issue
has been fixed by adding checks to validate the payload length field in the IPv6
packet header.
+ The implementation lacked sufficient checks to validate the IP version field
when a UDP/IPv6 packet is received with ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
disabled. This allowed the processing of packets with an incorrect IP version
field instead of rejecting them early. Subsequent attempts to extract network
buffers from these invalid UDP packets could result in dereferencing of an
invalid pointer due to incorrect pointer arithmetic.
We would like to thank Ivan Gotovchits of Mayhem Security for collaborating on
this issue through the coordinated vulnerability disclosure process.

Changes between FreeRTOS-plus-TCP V4.3.3 and V4.3.2 released June 10, 2025:
+ Fixed maximum network buffer allocation size check when buffer
allocation scheme 1 is used which caused allocation failure on
Expand Down
2 changes: 1 addition & 1 deletion docs/doxygen/config.doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ PROJECT_NAME = FreeRTOS-Plus-TCP
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = V4.3.3
PROJECT_NUMBER = V4.3.4

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
2 changes: 1 addition & 1 deletion manifest.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "FreeRTOS-Plus-TCP"
version: "V4.3.3"
version: "V4.3.4"
description:
"Thread safe FreeRTOS TCP/IP stack working on top of the FreeRTOS-Kernel to
implement the TCP/IP protocol. Suitable for microcontrollers."
Expand Down
24 changes: 11 additions & 13 deletions source/FreeRTOS_IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0U, 0U, 0U, 0U, 0U, 0
size_t uxBufferLength )
{
BaseType_t xResult = pdFAIL;
uint16_t ucVersionTrafficClass;
uint16_t usPayloadLength;
uint8_t ucNextHeader;
size_t uxMinimumLength;
Expand All @@ -116,15 +115,6 @@ const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0U, 0U, 0U, 0U, 0U, 0
break;
}

ucVersionTrafficClass = pxIPv6Packet->xIPHeader.ucVersionTrafficClass;

/* Test if the IP-version is 6. */
if( ( ( ucVersionTrafficClass & ( uint8_t ) 0xF0U ) >> 4 ) != 6U )
{
DEBUG_SET_TRACE_VARIABLE( xLocation, 2 );
break;
}

/* Check if the IPv6-header is transferred. */
if( uxBufferLength < ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ) )
{
Expand Down Expand Up @@ -497,6 +487,7 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI
const IPv6_Address_t * pxDestinationIPAddress = &( pxIPv6Header->xDestinationAddress );
const IPv6_Address_t * pxSourceIPAddress = &( pxIPv6Header->xSourceAddress );
BaseType_t xHasUnspecifiedAddress = pdFALSE;
uint16_t ucVersionTrafficClass = pxIPv6Header->ucVersionTrafficClass;

/* Drop if packet has unspecified IPv6 address (defined in RFC4291 - sec 2.5.2)
* either in source or destination address. */
Expand All @@ -506,10 +497,17 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI
xHasUnspecifiedAddress = pdTRUE;
}

/* Test if the IP-version is 6. */
if( ( ( ucVersionTrafficClass & ( uint8_t ) 0xF0U ) >> 4 ) != 6U )
{
/* Can not handle, unknown or invalid header version. */
eReturn = eReleaseBuffer;
FreeRTOS_printf( ( "prvAllowIPPacketIPv6: drop packet, invalid header version: %u\n", ( ucVersionTrafficClass & ( uint8_t ) 0xF0U ) >> 4 ) );
}
/* Is the packet for this IP address? */
if( ( xHasUnspecifiedAddress == pdFALSE ) &&
( pxNetworkBuffer->pxEndPoint != NULL ) &&
( memcmp( pxDestinationIPAddress->ucBytes, pxNetworkBuffer->pxEndPoint->ipv6_settings.xIPAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
else if( ( xHasUnspecifiedAddress == pdFALSE ) &&
( pxNetworkBuffer->pxEndPoint != NULL ) &&
( memcmp( pxDestinationIPAddress->ucBytes, pxNetworkBuffer->pxEndPoint->ipv6_settings.xIPAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
{
eReturn = eProcessBuffer;
}
Expand Down
14 changes: 12 additions & 2 deletions source/FreeRTOS_IPv6_Utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ BaseType_t prvChecksumIPv6Checks( uint8_t * pucEthernetBuffer,
{
uxExtensionHeaderLength = usGetExtensionHeaderLength( pucEthernetBuffer, uxBufferLength, &pxSet->ucProtocol );

if( uxExtensionHeaderLength >= uxBufferLength )
if( ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtensionHeaderLength ) >= uxBufferLength )
{
/* Error detected when parsing extension header. */
pxSet->usChecksum = ipINVALID_LENGTH;
Expand All @@ -107,8 +107,18 @@ BaseType_t prvChecksumIPv6Checks( uint8_t * pucEthernetBuffer,
/* coverity[misra_c_2012_rule_11_3_violation] */
pxSet->pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtensionHeaderLength ] ) );
pxSet->usPayloadLength = FreeRTOS_ntohs( pxSet->pxIPPacket_IPv6->usPayloadLength );

/* For IPv6, the number of bytes in the protocol is indicated. */
pxSet->usProtocolBytes = ( uint16_t ) ( pxSet->usPayloadLength - uxExtensionHeaderLength );
if( pxSet->usPayloadLength < uxExtensionHeaderLength )
{
/* Invalid payload length - extension headers exceed payload. */
pxSet->usChecksum = ipINVALID_LENGTH;
xReturn = 4;
}
else
{
pxSet->usProtocolBytes = ( uint16_t ) ( pxSet->usPayloadLength - uxExtensionHeaderLength );
}

uxNeeded = ( size_t ) pxSet->usPayloadLength;
uxNeeded += ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER;
Expand Down
Loading