summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2020-04-06 17:38:27 +0200
committerGitHub <noreply@github.com>2020-04-06 17:38:27 +0200
commitf728a3bb992767137a47ba09209d7712ff70ead5 (patch)
tree70ccec8ae466785237db2678a06e37906536e220
parente53181264a198c6f052f0556081b05caba9ec5c8 (diff)
parent628565c73d5289e8004abddb6c36b4384083f0f3 (diff)
Merge pull request #6158 from qlyoung/fix-cluster-list-uaf
bgpd: fix multiple bugs with cluster_list attrs
-rw-r--r--bgpd/bgp_attr.c20
-rw-r--r--bgpd/bgp_attr.h1
2 files changed, 11 insertions, 10 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c412ea0710..b3944e5f28 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -119,11 +119,11 @@ static void *cluster_hash_alloc(void *p)
/* Cluster list related functions. */
static struct cluster_list *cluster_parse(struct in_addr *pnt, int length)
{
- struct cluster_list tmp;
+ struct cluster_list tmp = {};
struct cluster_list *cluster;
tmp.length = length;
- tmp.list = pnt;
+ tmp.list = length == 0 ? NULL : pnt;
cluster = hash_get(cluster_hash, &tmp, cluster_hash_alloc);
cluster->refcnt++;
@@ -180,14 +180,16 @@ static struct cluster_list *cluster_intern(struct cluster_list *cluster)
return find;
}
-void cluster_unintern(struct cluster_list *cluster)
+static void cluster_unintern(struct cluster_list **cluster)
{
- if (cluster->refcnt)
- cluster->refcnt--;
+ if ((*cluster)->refcnt)
+ (*cluster)->refcnt--;
- if (cluster->refcnt == 0) {
- hash_release(cluster_hash, cluster);
- cluster_free(cluster);
+ if ((*cluster)->refcnt == 0) {
+ void *p = hash_release(cluster_hash, *cluster);
+ assert(p == *cluster);
+ cluster_free(*cluster);
+ *cluster = NULL;
}
}
@@ -1035,7 +1037,7 @@ void bgp_attr_unintern_sub(struct attr *attr)
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
if (attr->cluster)
- cluster_unintern(attr->cluster);
+ cluster_unintern(&attr->cluster);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
if (attr->transit)
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 6e91957f6a..94531313ae 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -335,7 +335,6 @@ extern unsigned long int attr_unknown_count(void);
/* Cluster list prototypes. */
extern bool cluster_loop_check(struct cluster_list *, struct in_addr);
-extern void cluster_unintern(struct cluster_list *);
/* Below exported for unit-test purposes only */
struct bgp_attr_parser_args {