From 5e57b5fc621300427d3818f0723b8cd8d5e5ca6a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Mar 2016 16:28:34 -0500 Subject: quagga: Remove double read of stream 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 --- 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 bee1a947..d0b9216a 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 a1a5bea7..4acaf8e8 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 0caf0014..c8f20d86 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 4531f13d..89404552 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 1411cd71..2670ff7e 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 e02b0989..72216164 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. */ -- cgit v1.2.3