]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Ensure that bgp open message stream has enough data to read
authorDonald Sharp <sharpd@nvidia.com>
Wed, 2 Nov 2022 17:24:48 +0000 (13:24 -0400)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Wed, 2 Nov 2022 19:47:00 +0000 (19:47 +0000)
If a operator receives an invalid packet that is of insufficient size
then it is possible for BGP to assert during reading of the packet
instead of gracefully resetting the connection with the peer.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit 766eec1b7accffe2c04a5c9ebb14e9f487bb9f78)

bgpd/bgp_packet.c

index a5f065a15c8ba405eb0975be2a3f1c7537295a3e..aaad0e000561ebf6d7223a11d7a0180fc550886f 100644 (file)
@@ -1327,8 +1327,27 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
            || CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) {
                uint8_t opttype;
 
+               if (STREAM_READABLE(peer->curr) < 1) {
+                       flog_err(
+                               EC_BGP_PKT_OPEN,
+                               "%s: stream does not have enough bytes for extended optional parameters",
+                               peer->host);
+                       bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+                                       BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+                       return BGP_Stop;
+               }
+
                opttype = stream_getc(peer->curr);
                if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) {
+                       if (STREAM_READABLE(peer->curr) < 2) {
+                               flog_err(
+                                       EC_BGP_PKT_OPEN,
+                                       "%s: stream does not have enough bytes to read the extended optional parameters optlen",
+                                       peer->host);
+                               bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+                                               BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+                               return BGP_Stop;
+                       }
                        optlen = stream_getw(peer->curr);
                        SET_FLAG(peer->sflags,
                                 PEER_STATUS_EXT_OPT_PARAMS_LENGTH);