afb66bcb7e
Resolves: #2196795 - denial of service by crafting a BGP OPEN message with an option of type 0xff Resolves: #2196796 - denial of service by crafting a BGP OPEN message with an option of type 0xff Resolves: #2196794 - out-of-bounds read exists in the BGP daemon of FRRouting
48 lines
1.6 KiB
Diff
48 lines
1.6 KiB
Diff
From 766eec1b7accffe2c04a5c9ebb14e9f487bb9f78 Mon Sep 17 00:00:00 2001
|
|
From: Donald Sharp <sharpd@nvidia.com>
|
|
Date: Wed, 2 Nov 2022 13:24:48 -0400
|
|
Subject: [PATCH] bgpd: Ensure that bgp open message stream has enough data to
|
|
read
|
|
|
|
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>
|
|
---
|
|
bgpd/bgp_packet.c | 19 +++++++++++++++++++
|
|
1 file changed, 19 insertions(+)
|
|
|
|
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
|
|
index 769f9613da8..72d6a923175 100644
|
|
--- a/bgpd/bgp_packet.c
|
|
+++ b/bgpd/bgp_packet.c
|
|
@@ -1386,8 +1386,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);
|