diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2024-05-06 13:33:18 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-06 13:33:18 +0200 |
| commit | 73dbcc9f9e415d9891032c718fd487411d0c7613 (patch) | |
| tree | 6c530bb649386326dfd153a5df9a58c62e18e026 | |
| parent | 28cf10ffea9b3a0245ba9efad9c3ddf1cfccfbeb (diff) | |
| parent | bbe8ca4c196136f085a4e9b0a30f7b43754c7b2b (diff) | |
Merge pull request #15934 from FRRouting/mergify/bp/stable/8.4/pr-15628
CVE-2024-31948
| -rw-r--r-- | bgpd/bgp_attr.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 0c69dd8878..13bc05d638 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1276,6 +1276,15 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, (args->startp - STREAM_DATA(BGP_INPUT(peer))) + 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) { /* where an attribute is relatively inconsequential, e.g. it does not * affect route selection, and can be safely ignored, then any such @@ -1285,6 +1294,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, case BGP_ATTR_AS4_AGGREGATOR: case BGP_ATTR_AGGREGATOR: case BGP_ATTR_ATOMIC_AGGREGATE: + case BGP_ATTR_PREFIX_SID: return BGP_ATTR_PARSE_PROCEED; /* Core attributes, particularly ones which may influence route @@ -1309,19 +1319,21 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode, notify_datap, length); 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; - - /* default to reset */ - return BGP_ATTR_PARSE_ERROR_NOTIFYPLS; + return BGP_ATTR_PARSE_WITHDRAW; } /* Find out what is wrong with the path attribute flag bits and log the error. @@ -2918,8 +2930,6 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args) struct attr *const attr = args->attr; enum bgp_attr_parse_ret ret; - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID); - uint8_t type; uint16_t length; size_t headersz = sizeof(type) + sizeof(length); @@ -2969,6 +2979,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; } |
