Skip to content

Commit fb6c62d

Browse files
Merge branch 'main' into TCP_ZeroCopyFix_PR
2 parents f3fcb34 + a91c311 commit fb6c62d

File tree

3 files changed

+178
-70
lines changed

3 files changed

+178
-70
lines changed

source/portable/BufferManagement/BufferAllocation_2.c

Lines changed: 113 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
#define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
6464
#endif /* ipconfigUSE_TCP == 1 */
6565

66+
#define baALIGNMENT_BYTES ( sizeof( size_t ) )
67+
#define baALIGNMENT_MASK ( baALIGNMENT_BYTES - 1U )
68+
#define baADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( SIZE_MAX - ( b ) ) )
69+
6670
/* Compile time assertion with zero runtime effects
6771
* it will assert on 'e' not being zero, as it tries to divide by it,
6872
* will also print the line where the error occurred in case of failure */
@@ -175,8 +179,11 @@ BaseType_t xNetworkBuffersInitialise( void )
175179

176180
uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
177181
{
178-
uint8_t * pucEthernetBuffer;
182+
uint8_t * pucEthernetBuffer = NULL;
183+
size_t uxMaxAllowedBytes = ( SIZE_MAX >> 1 );
179184
size_t xSize = *pxRequestedSizeBytes;
185+
size_t xBytesRequiredForAlignment, xAllocatedBytes;
186+
BaseType_t xIntegerOverflowed = pdFALSE;
180187

181188
if( xSize < baMINIMAL_BUFFER_SIZE )
182189
{
@@ -187,25 +194,46 @@ uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
187194

188195
/* Round up xSize to the nearest multiple of N bytes,
189196
* where N equals 'sizeof( size_t )'. */
190-
if( ( xSize & ( sizeof( size_t ) - 1U ) ) != 0U )
197+
if( ( xSize & baALIGNMENT_MASK ) != 0U )
191198
{
192-
xSize = ( xSize | ( sizeof( size_t ) - 1U ) ) + 1U;
193-
}
199+
xBytesRequiredForAlignment = baALIGNMENT_BYTES - ( xSize & baALIGNMENT_MASK );
194200

195-
*pxRequestedSizeBytes = xSize;
201+
if( baADD_WILL_OVERFLOW( xSize, xBytesRequiredForAlignment ) == 0 )
202+
{
203+
xSize += xBytesRequiredForAlignment;
204+
}
205+
else
206+
{
207+
xIntegerOverflowed = pdTRUE;
208+
}
209+
}
196210

197-
/* Allocate a buffer large enough to store the requested Ethernet frame size
198-
* and a pointer to a network buffer structure (hence the addition of
199-
* ipBUFFER_PADDING bytes). */
200-
pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
201-
configASSERT( pucEthernetBuffer != NULL );
211+
if( baADD_WILL_OVERFLOW( xSize, ipBUFFER_PADDING ) == 0 )
212+
{
213+
xAllocatedBytes = xSize + ipBUFFER_PADDING;
214+
}
215+
else
216+
{
217+
xIntegerOverflowed = pdTRUE;
218+
}
202219

203-
if( pucEthernetBuffer != NULL )
220+
if( ( xIntegerOverflowed == pdFALSE ) && ( xAllocatedBytes <= uxMaxAllowedBytes ) )
204221
{
205-
/* Enough space is left at the start of the buffer to place a pointer to
206-
* the network buffer structure that references this Ethernet buffer.
207-
* Return a pointer to the start of the Ethernet buffer itself. */
208-
pucEthernetBuffer += ipBUFFER_PADDING;
222+
*pxRequestedSizeBytes = xSize;
223+
224+
/* Allocate a buffer large enough to store the requested Ethernet frame size
225+
* and a pointer to a network buffer structure (hence the addition of
226+
* ipBUFFER_PADDING bytes). */
227+
pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xAllocatedBytes );
228+
configASSERT( pucEthernetBuffer != NULL );
229+
230+
if( pucEthernetBuffer != NULL )
231+
{
232+
/* Enough space is left at the start of the buffer to place a pointer to
233+
* the network buffer structure that references this Ethernet buffer.
234+
* Return a pointer to the start of the Ethernet buffer itself. */
235+
pucEthernetBuffer += ipBUFFER_PADDING;
236+
}
209237
}
210238

211239
return pucEthernetBuffer;
@@ -234,8 +262,51 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS
234262
size_t uxCount;
235263
size_t uxMaxAllowedBytes = ( SIZE_MAX >> 1 );
236264
size_t xRequestedSizeBytesCopy = xRequestedSizeBytes;
265+
size_t xBytesRequiredForAlignment, xAllocatedBytes;
266+
BaseType_t xIntegerOverflowed = pdFALSE;
267+
268+
if( ( xRequestedSizeBytesCopy < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
269+
{
270+
/* ARP packets can replace application packets, so the storage must be
271+
* at least large enough to hold an ARP. */
272+
xRequestedSizeBytesCopy = baMINIMAL_BUFFER_SIZE;
273+
}
274+
275+
/* Add 2 bytes to xRequestedSizeBytesCopy and round up xRequestedSizeBytesCopy
276+
* to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
277+
if( baADD_WILL_OVERFLOW( xRequestedSizeBytesCopy, 2 ) == 0 )
278+
{
279+
xRequestedSizeBytesCopy += 2U;
280+
}
281+
else
282+
{
283+
xIntegerOverflowed = pdTRUE;
284+
}
285+
286+
if( ( xRequestedSizeBytesCopy & baALIGNMENT_MASK ) != 0U )
287+
{
288+
xBytesRequiredForAlignment = baALIGNMENT_BYTES - ( xRequestedSizeBytesCopy & baALIGNMENT_MASK );
289+
290+
if( baADD_WILL_OVERFLOW( xRequestedSizeBytesCopy, xBytesRequiredForAlignment ) == 0 )
291+
{
292+
xRequestedSizeBytesCopy += xBytesRequiredForAlignment;
293+
}
294+
else
295+
{
296+
xIntegerOverflowed = pdTRUE;
297+
}
298+
}
299+
300+
if( baADD_WILL_OVERFLOW( xRequestedSizeBytesCopy, ipBUFFER_PADDING ) == 0 )
301+
{
302+
xAllocatedBytes = xRequestedSizeBytesCopy + ipBUFFER_PADDING;
303+
}
304+
else
305+
{
306+
xIntegerOverflowed = pdTRUE;
307+
}
237308

238-
if( ( xRequestedSizeBytesCopy <= uxMaxAllowedBytes ) && ( xNetworkBufferSemaphore != NULL ) )
309+
if( ( xIntegerOverflowed == pdFALSE ) && ( xAllocatedBytes <= uxMaxAllowedBytes ) && ( xNetworkBufferSemaphore != NULL ) )
239310
{
240311
/* If there is a semaphore available, there is a network buffer available. */
241312
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
@@ -261,25 +332,9 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS
261332

262333
if( xRequestedSizeBytesCopy > 0U )
263334
{
264-
if( ( xRequestedSizeBytesCopy < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
265-
{
266-
/* ARP packets can replace application packets, so the storage must be
267-
* at least large enough to hold an ARP. */
268-
xRequestedSizeBytesCopy = baMINIMAL_BUFFER_SIZE;
269-
}
270-
271-
/* Add 2 bytes to xRequestedSizeBytesCopy and round up xRequestedSizeBytesCopy
272-
* to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
273-
xRequestedSizeBytesCopy += 2U;
274-
275-
if( ( xRequestedSizeBytesCopy & ( sizeof( size_t ) - 1U ) ) != 0U )
276-
{
277-
xRequestedSizeBytesCopy = ( xRequestedSizeBytesCopy | ( sizeof( size_t ) - 1U ) ) + 1U;
278-
}
279-
280335
/* Extra space is obtained so a pointer to the network buffer can
281336
* be stored at the beginning of the buffer. */
282-
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytesCopy + ipBUFFER_PADDING );
337+
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xAllocatedBytes );
283338

284339
if( pxReturn->pucEthernetBuffer == NULL )
285340
{
@@ -403,32 +458,38 @@ NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDe
403458
size_t uxSizeBytes = xNewSizeBytes;
404459
NetworkBufferDescriptor_t * pxNetworkBufferCopy = pxNetworkBuffer;
405460

406-
407-
408461
xOriginalLength = pxNetworkBufferCopy->xDataLength + ipBUFFER_PADDING;
409-
uxSizeBytes = uxSizeBytes + ipBUFFER_PADDING;
410-
411-
pucBuffer = pucGetNetworkBuffer( &( uxSizeBytes ) );
412462

413-
if( pucBuffer == NULL )
414-
{
415-
/* In case the allocation fails, return NULL. */
416-
pxNetworkBufferCopy = NULL;
417-
}
418-
else
463+
if( baADD_WILL_OVERFLOW( uxSizeBytes, ipBUFFER_PADDING ) == 0 )
419464
{
420-
pxNetworkBufferCopy->xDataLength = uxSizeBytes;
465+
uxSizeBytes = uxSizeBytes + ipBUFFER_PADDING;
421466

422-
if( uxSizeBytes > xOriginalLength )
467+
pucBuffer = pucGetNetworkBuffer( &( uxSizeBytes ) );
468+
469+
if( pucBuffer == NULL )
423470
{
424-
uxSizeBytes = xOriginalLength;
471+
/* In case the allocation fails, return NULL. */
472+
pxNetworkBufferCopy = NULL;
425473
}
474+
else
475+
{
476+
pxNetworkBufferCopy->xDataLength = uxSizeBytes;
426477

427-
( void ) memcpy( pucBuffer - ipBUFFER_PADDING,
428-
pxNetworkBufferCopy->pucEthernetBuffer - ipBUFFER_PADDING,
429-
uxSizeBytes );
430-
vReleaseNetworkBuffer( pxNetworkBufferCopy->pucEthernetBuffer );
431-
pxNetworkBufferCopy->pucEthernetBuffer = pucBuffer;
478+
if( uxSizeBytes > xOriginalLength )
479+
{
480+
uxSizeBytes = xOriginalLength;
481+
}
482+
483+
( void ) memcpy( pucBuffer - ipBUFFER_PADDING,
484+
pxNetworkBufferCopy->pucEthernetBuffer - ipBUFFER_PADDING,
485+
uxSizeBytes );
486+
vReleaseNetworkBuffer( pxNetworkBufferCopy->pucEthernetBuffer );
487+
pxNetworkBufferCopy->pucEthernetBuffer = pucBuffer;
488+
}
489+
}
490+
else
491+
{
492+
pxNetworkBufferCopy = NULL;
432493
}
433494

434495
return pxNetworkBufferCopy;

source/portable/NetworkInterface/DriverSAM/NetworkInterface.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,17 @@ static void hand_tx_errors( void );
204204
static uint16_t prvGenerateCRC16( const uint8_t * pucAddress );
205205
static void prvAddMulticastMACAddress( const uint8_t * ucMacAddress );
206206

207+
/* Checks IP queue, buffers, and semaphore and logs diagnostic info if configured */
208+
static void vCheckBuffersAndQueue( void );
209+
210+
/* return 'puc_buffer' to the pool of transmission buffers. */
211+
void returnTxBuffer( uint8_t * puc_buffer );
212+
207213
/*-----------------------------------------------------------*/
208214

209215
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
210216
static BaseType_t xGMACSwitchRequired;
211217

212-
/* LLMNR multicast address. */
213-
static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
214-
215218
/* The GMAC object as defined by the ASF drivers. */
216219
static gmac_device_t gs_gmac_dev;
217220

@@ -454,8 +457,6 @@ static BaseType_t xPHY_Write( BaseType_t xAddress,
454457

455458
static BaseType_t prvSAM_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface )
456459
{
457-
const TickType_t x5_Seconds = 5000UL;
458-
459460
if( xEMACTaskHandle == NULL )
460461
{
461462
prvGMACInit( pxInterface );
@@ -673,9 +674,7 @@ static BaseType_t prvSAM_NetworkInterfaceOutput( NetworkInterface_t * pxInterfac
673674

674675
static BaseType_t prvGMACInit( NetworkInterface_t * pxInterface )
675676
{
676-
uint32_t ncfgr;
677677
NetworkEndPoint_t * pxEndPoint;
678-
BaseType_t xEntry = 1;
679678

680679
gmac_options_t gmac_option;
681680

@@ -1065,7 +1064,7 @@ volatile UBaseType_t uxLastMinBufferCount = 0;
10651064
volatile UBaseType_t uxCurrentSemCount;
10661065
volatile UBaseType_t uxLowestSemCount;
10671066

1068-
void vCheckBuffersAndQueue( void )
1067+
static void vCheckBuffersAndQueue( void )
10691068
{
10701069
static UBaseType_t uxCurrentCount;
10711070

@@ -1126,14 +1125,14 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB
11261125
static void prvEMACHandlerTask( void * pvParameters )
11271126
{
11281127
UBaseType_t uxCount;
1129-
UBaseType_t uxLowestSemCount = GMAC_TX_BUFFERS + 1;
1128+
1129+
uxLowestSemCount = GMAC_TX_BUFFERS + 1;
11301130

11311131
#if ( ipconfigZERO_COPY_TX_DRIVER != 0 )
11321132
NetworkBufferDescriptor_t * pxBuffer;
11331133
#endif
11341134
uint8_t * pucBuffer;
11351135
BaseType_t xResult = 0;
1136-
uint32_t xStatus;
11371136
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
11381137
uint32_t ulISREvents = 0U;
11391138

0 commit comments

Comments
 (0)