diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-10-01 20:40:15 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-01 20:40:15 +0300 |
| commit | 5cb79bd567672c5adab60de941079c1c25ca213e (patch) | |
| tree | 69f5bb500d282c9a6ddaad9a972a0e86cb16a1bd | |
| parent | 5ae96447d7e0b6f5e3a361b61b743b7e92e6832e (diff) | |
| parent | 1117baca3c592877a4d8a13ed6a1d9bd83977487 (diff) | |
Merge pull request #12043 from donaldsharp/bgp_hate
Bgp hate
| -rw-r--r-- | bgpd/bgp_open.c | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 7248f034a5..d1667fac26 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -1185,15 +1185,30 @@ as_t peek_for_as4_capability(struct peer *peer, uint16_t length) uint8_t opt_type; uint16_t opt_length; - /* Check the length. */ - if (stream_get_getp(s) + 2 > end) + /* Ensure we can read the option type */ + if (stream_get_getp(s) + 1 > end) goto end; - /* Fetch option type and length. */ + /* Fetch the option type */ opt_type = stream_getc(s); - opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) - ? stream_getw(s) - : stream_getc(s); + + /* + * Check the length and fetch the opt_length + * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) + * then we do a getw which is 2 bytes. So we need to + * ensure that we can read that as well + */ + if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { + if (stream_get_getp(s) + 2 > end) + goto end; + + opt_length = stream_getw(s); + } else { + if (stream_get_getp(s) + 1 > end) + goto end; + + opt_length = stream_getc(s); + } /* Option length check. */ if (stream_get_getp(s) + opt_length > end) @@ -1263,19 +1278,40 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, uint8_t opt_type; uint16_t opt_length; - /* Must have at least an OPEN option header */ - if (STREAM_READABLE(s) < 2) { + /* + * Check that we can read the opt_type and fetch it + */ + if (STREAM_READABLE(s) < 1) { zlog_info("%s Option length error", peer->host); bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } - - /* Fetch option type and length. */ opt_type = stream_getc(s); - opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) - ? stream_getw(s) - : stream_getc(s); + + /* + * Check the length of the stream to ensure that + * FRR can properly read the opt_length. Then read it + */ + if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { + if (STREAM_READABLE(s) < 2) { + zlog_info("%s Option length error", peer->host); + bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_MALFORMED_ATTR); + return -1; + } + + opt_length = stream_getw(s); + } else { + if (STREAM_READABLE(s) < 1) { + zlog_info("%s Option length error", peer->host); + bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_MALFORMED_ATTR); + return -1; + } + + opt_length = stream_getc(s); + } /* Option length check. */ if (STREAM_READABLE(s) < opt_length) { |
