@@ -820,13 +820,19 @@ struct bgp_notify bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify)
820820{
821821 struct bgp_notify bn = {};
822822
823+ /* Validate inner length */
824+ if (notify -> length < 2 )
825+ goto done ;
826+
823827 bn .code = notify -> raw_data [0 ];
824828 bn .subcode = notify -> raw_data [1 ];
825829 bn .length = notify -> length - 2 ;
830+ if (bn .length > 0 ) {
831+ bn .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , bn .length );
832+ memcpy (bn .raw_data , notify -> raw_data + 2 , bn .length );
833+ }
826834
827- bn .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , bn .length );
828- memcpy (bn .raw_data , notify -> raw_data + 2 , bn .length );
829-
835+ done :
830836 return bn ;
831837}
832838
@@ -2515,6 +2521,14 @@ static int bgp_notify_receive(struct peer_connection *connection,
25152521 struct bgp_notify inner = {};
25162522 bool hard_reset = false;
25172523
2524+ /* Validate message size */
2525+ if (size < 2 ) {
2526+ flog_err (EC_BGP_NOTIFY_RCV ,
2527+ "%s [Error] Notify packet error (packet length is short)" ,
2528+ peer -> host );
2529+ return BGP_Stop ;
2530+ }
2531+
25182532 if (peer -> notify .data ) {
25192533 XFREE (MTYPE_BGP_NOTIFICATION , peer -> notify .data );
25202534 peer -> notify .length = 0 ;
@@ -2526,16 +2540,24 @@ static int bgp_notify_receive(struct peer_connection *connection,
25262540 outer .length = size - 2 ;
25272541 outer .data = NULL ;
25282542 outer .raw_data = NULL ;
2529- if (outer .length ) {
2543+ if (outer .length > 0 ) {
25302544 outer .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , outer .length );
25312545 memcpy (outer .raw_data , stream_pnt (peer -> curr ), outer .length );
25322546 }
25332547
25342548 hard_reset =
25352549 bgp_notify_received_hard_reset (peer , outer .code , outer .subcode );
2536- if (hard_reset && outer . length ) {
2537- inner = bgp_notify_decapsulate_hard_reset ( & outer );
2550+ if (hard_reset ) {
2551+ /* Hard reset treatment: we expect but don't require inner error codes */
25382552 peer -> notify .hard_reset = true;
2553+ /* If we have at least an inner code and subcode, capture them */
2554+ if (outer .length > 1 ) {
2555+ inner = bgp_notify_decapsulate_hard_reset (& outer );
2556+ } else {
2557+ inner = outer ;
2558+ inner .length = 0 ;
2559+ inner .raw_data = NULL ;
2560+ }
25392561 } else {
25402562 inner = outer ;
25412563 }
@@ -2544,7 +2566,7 @@ static int bgp_notify_receive(struct peer_connection *connection,
25442566 peer -> notify .code = inner .code ;
25452567 peer -> notify .subcode = inner .subcode ;
25462568 /* For further diagnostic record returned Data. */
2547- if (inner .length ) {
2569+ if (inner .length > 0 ) {
25482570 peer -> notify .length = inner .length ;
25492571 peer -> notify .data =
25502572 XMALLOC (MTYPE_BGP_NOTIFICATION , inner .length );
@@ -2557,7 +2579,7 @@ static int bgp_notify_receive(struct peer_connection *connection,
25572579 int first = 0 ;
25582580 char c [4 ];
25592581
2560- if (inner .length ) {
2582+ if (inner .length > 0 ) {
25612583 inner .data = XMALLOC (MTYPE_BGP_NOTIFICATION ,
25622584 inner .length * 3 );
25632585 for (i = 0 ; i < inner .length ; i ++ )
@@ -2579,19 +2601,20 @@ static int bgp_notify_receive(struct peer_connection *connection,
25792601 }
25802602
25812603 bgp_notify_print (peer , & inner , "received" , hard_reset );
2582- if (inner .length ) {
2604+ if (inner .length > 0 ) {
25832605 XFREE (MTYPE_BGP_NOTIFICATION , inner .data );
25842606 inner .length = 0 ;
25852607 }
2586- if (outer .length ) {
2587- XFREE (MTYPE_BGP_NOTIFICATION , outer .data );
2588- XFREE (MTYPE_BGP_NOTIFICATION , outer .raw_data );
2589-
2608+ if (outer .length > 0 ) {
25902609 /* If this is a Hard Reset notification, we MUST free
25912610 * the inner (encapsulated) notification too.
25922611 */
2593- if (hard_reset )
2612+ if (hard_reset && ( inner . raw_data != outer . raw_data ) )
25942613 XFREE (MTYPE_BGP_NOTIFICATION , inner .raw_data );
2614+
2615+ XFREE (MTYPE_BGP_NOTIFICATION , outer .data );
2616+ XFREE (MTYPE_BGP_NOTIFICATION , outer .raw_data );
2617+
25952618 outer .length = 0 ;
25962619 }
25972620 }
0 commit comments