diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2020-04-06 17:38:27 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-06 17:38:27 +0200 |
| commit | f728a3bb992767137a47ba09209d7712ff70ead5 (patch) | |
| tree | 70ccec8ae466785237db2678a06e37906536e220 | |
| parent | e53181264a198c6f052f0556081b05caba9ec5c8 (diff) | |
| parent | 628565c73d5289e8004abddb6c36b4384083f0f3 (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.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_attr.h | 1 |
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 { |
