Skip to content

Commit fda028e

Browse files
Merge branch 'main' into fix_dhcp_network_buffer_leak
2 parents b88da23 + c78910a commit fda028e

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

source/FreeRTOS_DHCP.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@
264264
pxIterator = NULL;
265265
}
266266

267-
if( pxIterator != NULL )
267+
if( ( pxIterator != NULL ) && ( pxIterator->xDHCPData.eDHCPState == pxIterator->xDHCPData.eExpectedState ) )
268268
{
269269
/* The second parameter pdTRUE tells to check for a UDP message. */
270270
vDHCPProcessEndPoint( pdFALSE, pdTRUE, pxIterator );
@@ -276,15 +276,24 @@
276276
}
277277
else
278278
{
279-
/* Target not found, fetch the message and delete it. */
279+
/* Target not found or there is a state mismatch, fetch the message and delete it. */
280280
/* PAss the address of a pointer pucUDPPayload, because zero-copy is used. */
281281
lBytes = FreeRTOS_recvfrom( EP_DHCPData.xDHCPSocket, &( pucUDPPayload ), 0, FREERTOS_ZERO_COPY, NULL, NULL );
282282

283283
if( ( lBytes > 0 ) && ( pucUDPPayload != NULL ) )
284284
{
285285
/* Remove it now, destination not found. */
286286
FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayload );
287-
FreeRTOS_printf( ( "vDHCPProcess: Removed a %d-byte message: target not found\n", ( int ) lBytes ) );
287+
288+
if( pxIterator == NULL )
289+
{
290+
FreeRTOS_printf( ( "vDHCPProcess: Removed a %d-byte message: target not found\n", ( int ) lBytes ) );
291+
}
292+
else
293+
{
294+
FreeRTOS_printf( ( "vDHCPProcess: Wrong state: expected: %d got: %d : ignore\n",
295+
pxIterator->xDHCPData.eExpectedState, pxIterator->xDHCPData.eDHCPState ) );
296+
}
288297
}
289298
}
290299
}
@@ -496,6 +505,11 @@
496505
{
497506
/* Give up, start again. */
498507
EP_DHCPData.eDHCPState = eInitialWait;
508+
509+
/* Reset expected state so that DHCP packets from
510+
* different DHCP servers if available already in the DHCP socket can
511+
* be processed */
512+
EP_DHCPData.eExpectedState = eInitialWait;
499513
}
500514
}
501515
}
@@ -999,6 +1013,11 @@
9991013
{
10001014
/* Start again. */
10011015
EP_DHCPData.eDHCPState = eInitialWait;
1016+
1017+
/* Reset expected state so that DHCP packets from
1018+
* different DHCP servers if available already in the DHCP socket can
1019+
* be processed */
1020+
EP_DHCPData.eExpectedState = eInitialWait;
10021021
}
10031022
}
10041023

test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_stubs.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,4 +715,38 @@ static int32_t FreeRTOS_recvfrom_eWaitingOfferRecvfromSuccess_LocalMACAddrNotMat
715715

716716
return xSizeofUDPBuffer;
717717
}
718+
719+
static int32_t FreeRTOS_recvfrom_LoopedCall( const ConstSocket_t xSocket,
720+
void * pvBuffer,
721+
size_t uxBufferLength,
722+
BaseType_t xFlags,
723+
struct freertos_sockaddr * pxSourceAddress,
724+
socklen_t * pxSourceAddressLength,
725+
int callbacks )
726+
{
727+
NetworkEndPoint_t * pxIterator = pxNetworkEndPoints;
728+
size_t xSizeRetBufferSize = xSizeofUDPBuffer;
729+
730+
if( callbacks == 2 )
731+
{
732+
pxNetworkEndPoints->xDHCPData.eDHCPState = eInitialWait;
733+
}
734+
else if( callbacks == 4 )
735+
{
736+
xSizeRetBufferSize = 200;
737+
}
738+
739+
if( ( xFlags & FREERTOS_ZERO_COPY ) != 0 )
740+
{
741+
*( ( uint8_t ** ) pvBuffer ) = pucUDPBuffer;
742+
}
743+
744+
memset( pucUDPBuffer, 0, xSizeofUDPBuffer );
745+
/* Put in correct DHCP cookie. */
746+
( ( struct xDHCPMessage_IPv4 * ) pucUDPBuffer )->ulDHCPCookie = dhcpCOOKIE;
747+
( ( struct xDHCPMessage_IPv4 * ) pucUDPBuffer )->ucOpcode = dhcpREPLY_OPCODE;
748+
( ( struct xDHCPMessage_IPv4 * ) pucUDPBuffer )->ulTransactionID = FreeRTOS_htonl( 0x01ABCDEF );
749+
750+
return xSizeRetBufferSize;
751+
}
718752
/*-----------------------------------------------------------*/

test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,49 @@ void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage( void )
13241324
TEST_ASSERT_EQUAL( eLeasedAddress, pxEndPoint->xDHCPData.eDHCPState );
13251325
}
13261326

1327+
/**
1328+
*@brief This test function ensures that when the DHCP states are mismatching after
1329+
* initial parsing of response from DHCP server, if a new response from a different DHCP
1330+
* server will cause a infinite loop inside the vDHCPProcess.
1331+
*/
1332+
void test_vDHCPProcess_eLeasedAddress_InCorrectState_Loop( void )
1333+
{
1334+
struct xSOCKET xTestSocket;
1335+
NetworkEndPoint_t xEndPoint = { 0 }, * pxEndPoint = &xEndPoint;
1336+
uint8_t * pucUDPPayload;
1337+
1338+
/* This should remain unchanged. */
1339+
xDHCPv4Socket = &xTestSocket;
1340+
xDHCPSocketUserCount = 1;
1341+
pxEndPoint->xDHCPData.xDHCPSocket = &xTestSocket;
1342+
/* Put the required state. */
1343+
pxEndPoint->xDHCPData.eDHCPState = eLeasedAddress;
1344+
pxEndPoint->xDHCPData.eExpectedState = eLeasedAddress;
1345+
pxEndPoint->xDHCPData.ulTransactionId = 0x01ABCDEF;
1346+
1347+
/* Make sure that the local IP address is uninitialised. */
1348+
pxEndPoint->ipv4_settings.ulIPAddress = 0;
1349+
/* Put a verifiable value. */
1350+
memset( &pxEndPoint->ipv4_settings, 0xAA, sizeof( IPV4Parameters_t ) );
1351+
/* Put a verifiable value. */
1352+
memset( &pxEndPoint->ipv4_defaults, 0xBB, sizeof( IPV4Parameters_t ) );
1353+
1354+
pxNetworkEndPoints = pxEndPoint;
1355+
1356+
/* Expect these arguments. */
1357+
FreeRTOS_recvfrom_Stub( FreeRTOS_recvfrom_LoopedCall );
1358+
1359+
FreeRTOS_ReleaseUDPPayloadBuffer_Expect( pucUDPBuffer );
1360+
1361+
FreeRTOS_IsEndPointUp_IgnoreAndReturn( pdFALSE );
1362+
1363+
FreeRTOS_ReleaseUDPPayloadBuffer_Ignore();
1364+
1365+
vDHCPProcess( pdFALSE, pxEndPoint );
1366+
1367+
TEST_ASSERT_EQUAL( eInitialWait, pxEndPoint->xDHCPData.eDHCPState );
1368+
}
1369+
13271370
void test_vDHCPProcess_eLeasedAddress_CorrectState_ValidBytesInMessage_TransactionIDMismatch( void )
13281371
{
13291372
struct xSOCKET xTestSocket;

0 commit comments

Comments
 (0)