mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-25 06:42:26 +00:00
Merge pull request #15628 from opensourcerouting/fix/bgp_prefix_sid_crash
bgpd: Fix error handling when receiving BGP Prefix SID attribute
This commit is contained in:
commit
6bea75f18c
@ -1389,6 +1389,15 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
|
|||||||
(args->startp - STREAM_DATA(BGP_INPUT(peer)))
|
(args->startp - STREAM_DATA(BGP_INPUT(peer)))
|
||||||
+ args->total);
|
+ args->total);
|
||||||
|
|
||||||
|
/* Partial optional attributes that are malformed should not cause
|
||||||
|
* the whole session to be reset. Instead treat it as a withdrawal
|
||||||
|
* of the routes, if possible.
|
||||||
|
*/
|
||||||
|
if (CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS) &&
|
||||||
|
CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL) &&
|
||||||
|
CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL))
|
||||||
|
return BGP_ATTR_PARSE_WITHDRAW;
|
||||||
|
|
||||||
switch (args->type) {
|
switch (args->type) {
|
||||||
/* where an attribute is relatively inconsequential, e.g. it does not
|
/* where an attribute is relatively inconsequential, e.g. it does not
|
||||||
* affect route selection, and can be safely ignored, then any such
|
* affect route selection, and can be safely ignored, then any such
|
||||||
@ -1398,6 +1407,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
|
|||||||
case BGP_ATTR_AS4_AGGREGATOR:
|
case BGP_ATTR_AS4_AGGREGATOR:
|
||||||
case BGP_ATTR_AGGREGATOR:
|
case BGP_ATTR_AGGREGATOR:
|
||||||
case BGP_ATTR_ATOMIC_AGGREGATE:
|
case BGP_ATTR_ATOMIC_AGGREGATE:
|
||||||
|
case BGP_ATTR_PREFIX_SID:
|
||||||
return BGP_ATTR_PARSE_PROCEED;
|
return BGP_ATTR_PARSE_PROCEED;
|
||||||
|
|
||||||
/* Core attributes, particularly ones which may influence route
|
/* Core attributes, particularly ones which may influence route
|
||||||
@ -1425,19 +1435,21 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
|
|||||||
BGP_NOTIFY_UPDATE_ERR, subcode,
|
BGP_NOTIFY_UPDATE_ERR, subcode,
|
||||||
notify_datap, length);
|
notify_datap, length);
|
||||||
return BGP_ATTR_PARSE_ERROR;
|
return BGP_ATTR_PARSE_ERROR;
|
||||||
|
default:
|
||||||
|
/* Unknown attributes, that are handled by this function
|
||||||
|
* should be treated as withdraw, to prevent one more CVE
|
||||||
|
* from being introduced.
|
||||||
|
* RFC 7606 says:
|
||||||
|
* The "treat-as-withdraw" approach is generally preferred
|
||||||
|
* and the "session reset" approach is discouraged.
|
||||||
|
*/
|
||||||
|
flog_err(EC_BGP_ATTR_FLAG,
|
||||||
|
"%s(%u) attribute received, while it is not known how to handle it, treating as withdraw",
|
||||||
|
lookup_msg(attr_str, args->type, NULL), args->type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Partial optional attributes that are malformed should not cause
|
|
||||||
* the whole session to be reset. Instead treat it as a withdrawal
|
|
||||||
* of the routes, if possible.
|
|
||||||
*/
|
|
||||||
if (CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)
|
|
||||||
&& CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
|
|
||||||
&& CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
return BGP_ATTR_PARSE_WITHDRAW;
|
return BGP_ATTR_PARSE_WITHDRAW;
|
||||||
|
|
||||||
/* default to reset */
|
|
||||||
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out what is wrong with the path attribute flag bits and log the error.
|
/* Find out what is wrong with the path attribute flag bits and log the error.
|
||||||
@ -3163,8 +3175,6 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
|
|||||||
struct attr *const attr = args->attr;
|
struct attr *const attr = args->attr;
|
||||||
enum bgp_attr_parse_ret ret;
|
enum bgp_attr_parse_ret ret;
|
||||||
|
|
||||||
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
|
|
||||||
|
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
size_t headersz = sizeof(type) + sizeof(length);
|
size_t headersz = sizeof(type) + sizeof(length);
|
||||||
@ -3214,6 +3224,8 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID));
|
||||||
|
|
||||||
return BGP_ATTR_PARSE_PROCEED;
|
return BGP_ATTR_PARSE_PROCEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user