The addition of a MIN(X,Y) with a stream_getc in the Y
causes a double read of the stream due to the way that
MIN is defined.

This fix removes a crash in all protocols.

Signed-off-by: Donald Sharp <sha...@cumulusnetworks.com>
---
 bgpd/bgp_zebra.c     | 8 ++++++--
 isisd/isis_zebra.c   | 4 +++-
 ospf6d/ospf6_zebra.c | 4 +++-
 ospfd/ospf_zebra.c   | 4 +++-
 ripd/rip_zebra.c     | 6 ++++--
 ripngd/ripng_zebra.c | 4 +++-
 6 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index bee1a94..d0b9216 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -238,6 +238,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, 
zebra_size_t length,
   struct zapi_ipv4 api;
   struct in_addr nexthop;
   struct prefix_ipv4 p;
+  unsigned char plength = 0;
 
   s = zclient->ibuf;
   nexthop.s_addr = 0;
@@ -250,7 +251,8 @@ zebra_read_ipv4 (int command, struct zclient *zclient, 
zebra_size_t length,
   /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv4));
   p.family = AF_INET;
-  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   /* Nexthop, ifindex, distance, metric. */
@@ -314,6 +316,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, 
zebra_size_t length,
   struct zapi_ipv6 api;
   struct in6_addr nexthop;
   struct prefix_ipv6 p;
+  unsigned char plength = 0;
 
   s = zclient->ibuf;
   memset (&nexthop, 0, sizeof (struct in6_addr));
@@ -326,7 +329,8 @@ zebra_read_ipv6 (int command, struct zclient *zclient, 
zebra_size_t length,
   /* IPv6 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));
   p.family = AF_INET6;
-  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   /* Nexthop, ifindex, distance, metric. */
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index a1a5bea..4acaf8e 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -529,6 +529,7 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient,
   struct prefix *p_generic = (struct prefix*)&p;
   unsigned long ifindex __attribute__ ((unused));
   struct in_addr nexthop __attribute__ ((unused));
+  unsigned char plength = 0;
 
   stream = zclient->ibuf;
   memset(&api, 0, sizeof(api));
@@ -541,7 +542,8 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient,
   api.message = stream_getc (stream);
 
   p.family = AF_INET;
-  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (stream));
+  plength = stream_getc (stream);
+  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
 
   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 0caf001..c8f20d8 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -213,6 +213,7 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
   unsigned long ifindex;
   struct prefix_ipv6 p;
   struct in6_addr *nexthop;
+  unsigned char plength = 0;
 
   s = zclient->ibuf;
   ifindex = 0;
@@ -227,7 +228,8 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
   /* IPv6 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));
   p.family = AF_INET6;
-  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   /* Nexthop, ifindex, distance, metric. */
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 4531f13..8940455 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -832,6 +832,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
   struct prefix_ipv4 p;
   struct external_info *ei;
   struct ospf *ospf;
+  unsigned char plength = 0;
 
   s = zclient->ibuf;
   ifindex = 0;
@@ -845,7 +846,8 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
   /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv4));
   p.family = AF_INET;
-  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   if (IPV4_NET127(ntohl(p.prefix.s_addr)))
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 1411cd7..2670ff7 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -135,7 +135,8 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, 
zebra_size_t length,
   unsigned long ifindex;
   struct in_addr nexthop;
   struct prefix_ipv4 p;
-  
+  unsigned char plength = 0;
+
   s = zclient->ibuf;
   ifindex = 0;
   nexthop.s_addr = 0;
@@ -148,7 +149,8 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, 
zebra_size_t length,
   /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv4));
   p.family = AF_INET;
-  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   /* Nexthop, ifindex, distance, metric. */
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index e02b098..7221616 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -134,6 +134,7 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
   unsigned long ifindex;
   struct in6_addr nexthop;
   struct prefix_ipv6 p;
+  unsigned char plength = 0;
 
   s = zclient->ibuf;
   ifindex = 0;
@@ -147,7 +148,8 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
   /* IPv6 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));
   p.family = AF_INET6;
-  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
+  plength = stream_getc (s);
+  p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
   /* Nexthop, ifindex, distance, metric. */
-- 
1.9.1


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to