summaryrefslogtreecommitdiff
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2024-03-27 19:08:38 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2024-03-29 09:13:11 +0200
commitbabb23b74855e23c987a63f8256d24e28c044d07 (patch)
tree8a32d0bf398c243b4b7127077469225ddc734571 /bgpd/bgp_attr.c
parentba6a8f1a31e1a88df2de69ea46068e8bd9b97138 (diff)
bgpd: Prevent from one more CVE triggering this place
If we receive an attribute that is handled by bgp_attr_malformed(), use treat-as-withdraw behavior for unknown (or missing to add - if new) attributes. Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 6c886b0061..e2321ad296 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1389,6 +1389,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
@@ -1426,19 +1435,21 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
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.