File quagga-13-CVE-2017-15865_rewind-fix.patch of Package quagga.35810

From bd2bdfd2c3eb225588613e835fa2dc074fd33081 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Wed, 18 Sep 2024 12:16:48 +0200
Subject: [PATCH 1/3] bgpd: fix mishandled attribute length
References: CVE-2017-15865,bsc#1230866

Backported fix from frr:
- commit dacffad46143fb57e5fa973fcbfbd0eb51ea37b2
  from https://github.com/FRRouting/frr/pull/1417
  ```
  Author: Quentin Young <qlyoung@cumulusnetworks.com>
  Subject: bgpd: fix mishandled attribute length

  A crafted BGP UPDATE with a malformed path attribute length field causes
  bgpd to dump up to 65535 bytes of application memory and send it as the
  data field in a BGP NOTIFY message, which is truncated to 4075 bytes
  after accounting for protocol headers. After reading a malformed length
  field, a NOTIFY is generated that is supposed to contain the problematic
  data, but the malformed length field is inadvertently used to compute
  how much data we send.

  CVE-2017-15865
  ```

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index fce4b542..fceb10cc 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2167,10 +2167,44 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
 	  zlog (peer->log, LOG_WARNING, 
 		"%s: BGP type %d length %d is too large, attribute total length is %d.  attr_endp is %p.  endp is %p", peer->host, type, length, size, attr_endp, endp);
 	  zlog_warn ("%s: BGP type %d length %d is too large, attribute total length is %d.  attr_endp is %p.  endp is %p", peer->host, type, length, size, attr_endp, endp);
+	  /*
+           * RFC 4271 6.3
+           * If any recognized attribute has an Attribute
+           * Length that conflicts with the expected length
+           * (based on the attribute type code), then the
+           * Error Subcode MUST be set to Attribute Length
+           * Error.  The Data field MUST contain the erroneous
+           * attribute (type, length, and value).
+           * ----------
+           * We do not currently have a good way to determine the
+           * length of the attribute independent of the length
+           * received in the message. Instead we send the
+           * minimum between the amount of data we have and the
+           * amount specified by the attribute length field.
+           *
+           * Instead of directly passing in the packet buffer and
+           * offset we use the stream_get* functions to read into
+           * a stack buffer, since they perform bounds checking
+           * and we are working with untrusted data.
+           */
+          unsigned char ndata[BGP_MAX_PACKET_SIZE];
+          memset(ndata, 0x00, sizeof(ndata));
+          size_t lfl = CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
+          /* Rewind to end of flag field */
+          stream_forward_getp(BGP_INPUT(peer), -(1 + lfl));
+          /* Type */
+          stream_get(&ndata[0], BGP_INPUT(peer), 1);
+          /* Length */
+          stream_get(&ndata[1], BGP_INPUT(peer), lfl);
+          /* Value */
+          size_t atl = attr_endp - startp;
+          size_t ndl = MIN(atl, STREAM_READABLE(BGP_INPUT(peer)));
+          stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl);
+
           bgp_notify_send_with_data (peer,
                                      BGP_NOTIFY_UPDATE_ERR,
                                      BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
-                                     startp, endp - startp);
+                                     ndata, ndl + lfl + 1);
 	  return BGP_ATTR_PARSE_ERROR;
 	}
 	
-- 
2.43.0


From 0f97e676f577d5364d19b136e9ee4fbca6b39fb9 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Wed, 18 Sep 2024 12:17:06 +0200
Subject: [PATCH 2/3] lib: add stream_rewind_getp()
References: CVE-2017-15865,bsc#1230866

Backport from frr:
- commit 06cf2c0c36e044dcdc4cdd5f7d6e971bc07a294c
  from https://github.com/FRRouting/frr/pull/7046
  ```
  Author: Quentin Young <qlyoung@nvidia.com>
  Subject: lib: add stream_rewind_getp()

  stream_forward_getp() cannot be used with negative numbers due to the
  size_t argument, we'll end up doing overflow arithmetic.
  ```

diff --git a/lib/stream.c b/lib/stream.c
index b50992d6..01434c18 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -272,6 +272,19 @@ stream_forward_getp (struct stream *s, size_t size)
   s->getp += size;
 }
 
+void stream_rewind_getp(struct stream *s, size_t size)
+{
+  STREAM_VERIFY_SANE(s);
+
+  if (size > s->getp || !GETP_VALID(s, s->getp - size))
+    {
+      STREAM_BOUND_WARN (s, "rewind getp");
+      return;
+    }
+
+  s->getp -= size;
+}
+
 void
 stream_forward_endp (struct stream *s, size_t size)
 {
diff --git a/lib/stream.h b/lib/stream.h
index 06b0ee12..c52f294c 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -159,6 +159,7 @@ extern struct stream *stream_dupcat(struct stream *s1, struct stream *s2,
 extern void stream_set_getp (struct stream *, size_t);
 extern void stream_set_endp (struct stream *, size_t);
 extern void stream_forward_getp (struct stream *, size_t);
+extern void stream_rewind_getp(struct stream *s, size_t size);
 extern void stream_forward_endp (struct stream *, size_t);
 
 /* steam_put: NULL source zeroes out size_t bytes of stream */
-- 
2.43.0


From 7b1f948357c92cfaf6fd7f9813ee2bcad2dfd242 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Wed, 18 Sep 2024 12:17:23 +0200
Subject: [PATCH 3/3] bgpd: use stream_rewind_getp() to remove overflow
References: CVE-2017-15865,bsc#1230866

Backported fix from frr:
- commit 763a5d3c2dc7e9061006d56a9a983c2a8be64765
  from https://github.com/FRRouting/frr/pull/7046
  ```
  Author: Quentin Young <qlyoung@nvidia.com>
  Subject: bgpd: use stream_rewind_getp() to remove overflow

  Passing a negative argument to a size_t parameter creates an overflow
  condition
  ```

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index fceb10cc..63a78d42 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2191,7 +2191,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
           memset(ndata, 0x00, sizeof(ndata));
           size_t lfl = CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
           /* Rewind to end of flag field */
-          stream_forward_getp(BGP_INPUT(peer), -(1 + lfl));
+          stream_rewind_getp(BGP_INPUT(peer), (1 + lfl));
           /* Type */
           stream_get(&ndata[0], BGP_INPUT(peer), 1);
           /* Length */
-- 
2.43.0

openSUSE Build Service is sponsored by