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
176180uint8_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 ;
0 commit comments