Skip to content
Merged

Bgp hate #12043

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 49 additions & 13 deletions bgpd/bgp_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down