routing/quagga/patches/003-Quagga-2018-1114.patch
Josef Schlehofer 839ea37939 quagga: update to version 1.1.1 (#541)
Makefile changes:
- Use HTTPS everywhere
- Reorder some things to have it in sync with other packages
- Fixed SPDX License Identifier
- Added PKG_LICENSE_FILES
- For checksum use SHA256

Refreshed patches

Fixes CVEs:
- CVE-2017-5495
- CVE-2017-16227

Fixes security issues:
- Quagga-2018-0543: attr_endp used for NOTIFY data
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-0543.txt
- Quagga-2018-1114: bgpd double free
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1114.txt
- Quagga-2018-1550: debug overrun in notify lookup tables
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1550.txt
- Quagga-2018-1975: BGP capability inf. loop
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1975.txt

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
2020-01-27 23:58:39 +01:00

99 lines
3 KiB
Diff

From e69b535f92eafb599329bf725d9b4c6fd5d7fded Mon Sep 17 00:00:00 2001
From: Paul Jakma <paul@jakma.org>
Date: Sat, 6 Jan 2018 19:52:10 +0000
Subject: bgpd/security: Fix double free of unknown attribute
Security issue: Quagga-2018-1114
See: https://www.quagga.net/security/Quagga-2018-1114.txt
It is possible for bgpd to double-free an unknown attribute. This can happen
via bgp_update_receive receiving an UPDATE with an invalid unknown attribute.
bgp_update_receive then will call bgp_attr_unintern_sub and bgp_attr_flush,
and the latter may try free an already freed unknown attr.
* bgpd/bgp_attr.c: (transit_unintern) Take a pointer to the caller's storage
for the (struct transit *), so that transit_unintern can NULL out the
caller's reference if the (struct transit) is freed.
(cluster_unintern) By inspection, appears to have a similar issue.
(bgp_attr_unintern_sub) adjust for above.
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -186,15 +186,17 @@ cluster_intern (struct cluster_list *clu
}
void
-cluster_unintern (struct cluster_list *cluster)
+cluster_unintern (struct cluster_list **cluster)
{
- if (cluster->refcnt)
- cluster->refcnt--;
+ struct cluster_list *c = *cluster;
+ if (c->refcnt)
+ c->refcnt--;
- if (cluster->refcnt == 0)
+ if (c->refcnt == 0)
{
- hash_release (cluster_hash, cluster);
- cluster_free (cluster);
+ hash_release (cluster_hash, c);
+ cluster_free (c);
+ *cluster = NULL;
}
}
@@ -344,15 +346,18 @@ transit_intern (struct transit *transit)
}
void
-transit_unintern (struct transit *transit)
+transit_unintern (struct transit **transit)
{
- if (transit->refcnt)
- transit->refcnt--;
+ struct transit *t = *transit;
+
+ if (t->refcnt)
+ t->refcnt--;
- if (transit->refcnt == 0)
+ if (t->refcnt == 0)
{
- hash_release (transit_hash, transit);
- transit_free (transit);
+ hash_release (transit_hash, t);
+ transit_free (t);
+ *transit = NULL;
}
}
@@ -793,11 +798,11 @@ bgp_attr_unintern_sub (struct attr *attr
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
if (attr->extra->cluster)
- cluster_unintern (attr->extra->cluster);
+ cluster_unintern (&attr->extra->cluster);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
if (attr->extra->transit)
- transit_unintern (attr->extra->transit);
+ transit_unintern (&attr->extra->transit);
}
}
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -184,10 +184,10 @@ extern unsigned long int attr_unknown_co
/* Cluster list prototypes. */
extern int cluster_loop_check (struct cluster_list *, struct in_addr);
-extern void cluster_unintern (struct cluster_list *);
+extern void cluster_unintern (struct cluster_list **);
/* Transit attribute prototypes. */
-void transit_unintern (struct transit *);
+void transit_unintern (struct transit **);
/* Below exported for unit-test purposes only */
struct bgp_attr_parser_args {