bgpd: Ensure FRR has enough data to read 2 bytes in bgp_open_option_parse

In bgp_open_option_parse the code is checking that the
stream has at least 2 bytes to read ( the opt_type and
the opt_length).  However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
is configured then FRR is reading 3 bytes.  Which is not good
since the packet could be badly formateed.  Ensure that
FRR has the appropriate data length to read the data.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
Donald Sharp 2022-09-30 08:57:43 -04:00
parent 3e46b43e37
commit 1117baca3c
1 changed files with 28 additions and 7 deletions

View File

@ -1278,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) {