@@ -803,13 +803,19 @@ struct bgp_notify bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify)
803803{
804804 struct bgp_notify bn = {};
805805
806+ /* Validate inner length */
807+ if (notify -> length < 2 )
808+ goto done ;
809+
806810 bn .code = notify -> raw_data [0 ];
807811 bn .subcode = notify -> raw_data [1 ];
808812 bn .length = notify -> length - 2 ;
813+ if (bn .length > 0 ) {
814+ bn .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , bn .length );
815+ memcpy (bn .raw_data , notify -> raw_data + 2 , bn .length );
816+ }
809817
810- bn .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , bn .length );
811- memcpy (bn .raw_data , notify -> raw_data + 2 , bn .length );
812-
818+ done :
813819 return bn ;
814820}
815821
@@ -2575,6 +2581,14 @@ static int bgp_notify_receive(struct peer_connection *connection,
25752581 struct bgp_notify inner = {};
25762582 bool hard_reset = false;
25772583
2584+ /* Validate message size */
2585+ if (size < 2 ) {
2586+ flog_err (EC_BGP_NOTIFY_RCV ,
2587+ "%s [Error] Notify packet error (packet length is short)" ,
2588+ peer -> host );
2589+ return BGP_Stop ;
2590+ }
2591+
25782592 if (peer -> notify .data ) {
25792593 XFREE (MTYPE_BGP_NOTIFICATION , peer -> notify .data );
25802594 peer -> notify .length = 0 ;
@@ -2586,16 +2600,24 @@ static int bgp_notify_receive(struct peer_connection *connection,
25862600 outer .length = size - 2 ;
25872601 outer .data = NULL ;
25882602 outer .raw_data = NULL ;
2589- if (outer .length ) {
2603+ if (outer .length > 0 ) {
25902604 outer .raw_data = XMALLOC (MTYPE_BGP_NOTIFICATION , outer .length );
25912605 memcpy (outer .raw_data , stream_pnt (connection -> curr ), outer .length );
25922606 }
25932607
25942608 hard_reset =
25952609 bgp_notify_received_hard_reset (peer , outer .code , outer .subcode );
2596- if (hard_reset && outer . length ) {
2597- inner = bgp_notify_decapsulate_hard_reset ( & outer );
2610+ if (hard_reset ) {
2611+ /* Hard reset treatment: we expect but don't require inner error codes */
25982612 peer -> notify .hard_reset = true;
2613+ /* If we have at least an inner code and subcode, capture them */
2614+ if (outer .length > 1 ) {
2615+ inner = bgp_notify_decapsulate_hard_reset (& outer );
2616+ } else {
2617+ inner = outer ;
2618+ inner .length = 0 ;
2619+ inner .raw_data = NULL ;
2620+ }
25992621 } else {
26002622 inner = outer ;
26012623 }
@@ -2604,7 +2626,7 @@ static int bgp_notify_receive(struct peer_connection *connection,
26042626 peer -> notify .code = inner .code ;
26052627 peer -> notify .subcode = inner .subcode ;
26062628 /* For further diagnostic record returned Data. */
2607- if (inner .length ) {
2629+ if (inner .length > 0 ) {
26082630 peer -> notify .length = inner .length ;
26092631 peer -> notify .data =
26102632 XMALLOC (MTYPE_BGP_NOTIFICATION , inner .length );
@@ -2617,7 +2639,7 @@ static int bgp_notify_receive(struct peer_connection *connection,
26172639 int first = 0 ;
26182640 char c [4 ];
26192641
2620- if (inner .length ) {
2642+ if (inner .length > 0 ) {
26212643 inner .data = XMALLOC (MTYPE_BGP_NOTIFICATION ,
26222644 inner .length * 3 );
26232645 for (i = 0 ; i < inner .length ; i ++ )
@@ -2639,19 +2661,20 @@ static int bgp_notify_receive(struct peer_connection *connection,
26392661 }
26402662
26412663 bgp_notify_print (peer , & inner , "received" , hard_reset );
2642- if (inner .length ) {
2664+ if (inner .length > 0 ) {
26432665 XFREE (MTYPE_BGP_NOTIFICATION , inner .data );
26442666 inner .length = 0 ;
26452667 }
2646- if (outer .length ) {
2647- XFREE (MTYPE_BGP_NOTIFICATION , outer .data );
2648- XFREE (MTYPE_BGP_NOTIFICATION , outer .raw_data );
2649-
2668+ if (outer .length > 0 ) {
26502669 /* If this is a Hard Reset notification, we MUST free
26512670 * the inner (encapsulated) notification too.
26522671 */
2653- if (hard_reset )
2672+ if (hard_reset && ( inner . raw_data != outer . raw_data ) )
26542673 XFREE (MTYPE_BGP_NOTIFICATION , inner .raw_data );
2674+
2675+ XFREE (MTYPE_BGP_NOTIFICATION , outer .data );
2676+ XFREE (MTYPE_BGP_NOTIFICATION , outer .raw_data );
2677+
26552678 outer .length = 0 ;
26562679 }
26572680 }
0 commit comments