]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: fix Prefix-SID parse error
authorHiroki Shirokura <slank.dev@gmail.com>
Mon, 3 Feb 2020 23:25:26 +0000 (23:25 +0000)
committerHiroki Shirokura <slank.dev@gmail.com>
Fri, 14 Feb 2020 00:13:43 +0000 (00:13 +0000)
Prefix-SID is desined to capable for TLV array.
That behaviour is important to support SR-MPLS feature
and that supported by previous PR #5418.

In that implementation, but if some additional data
(such as next BGP update message or next path attributes)
was present after Prefix-SID path attribute,
bgpd will parse that addional data as Prefix-SID TLV.

This commit fix that. before this commit, loop condition
is determed by stream is readable or not. In more correct
implementatoin, the prefix-sid boundaly should be checked
additonally. the length of Prefix-sid path attribute can
be get by bgp_attr_parse_args.

Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
bgpd/bgp_attr.c

index f00bb2b3cd49fd86c0e1faa73efc4d4c45101574..2bbcade8e8ef7436a9f010a4310ef84cc99974ce 100644 (file)
@@ -2590,8 +2590,10 @@ bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args,
        uint8_t type;
        uint16_t length;
        size_t headersz = sizeof(type) + sizeof(length);
+       size_t psid_parsed_length = 0;
 
-       while (STREAM_READABLE(peer->curr) > 0) {
+       while (STREAM_READABLE(peer->curr) > 0
+              && psid_parsed_length < args->length) {
 
                if (STREAM_READABLE(peer->curr) < headersz) {
                        flog_err(
@@ -2621,6 +2623,19 @@ bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args,
 
                if (ret != BGP_ATTR_PARSE_PROCEED)
                        return ret;
+
+               psid_parsed_length += length + headersz;
+
+               if (psid_parsed_length > args->length) {
+                       flog_err(
+                               EC_BGP_ATTR_LEN,
+                               "Malformed Prefix SID attribute - TLV overflow by attribute (need %zu"
+                               " for TLV length, have %zu overflowed in UPDATE)",
+                               length + headersz, psid_parsed_length - (length + headersz));
+                       return bgp_attr_malformed(
+                               args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+                               args->total);
+               }
        }
 
        return BGP_ATTR_PARSE_PROCEED;