]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] use-after-free in isc_radix_remove()
authorEvan Hunt <each@isc.org>
Tue, 29 Apr 2014 22:21:46 +0000 (15:21 -0700)
committerEvan Hunt <each@isc.org>
Tue, 29 Apr 2014 22:21:46 +0000 (15:21 -0700)
3826. [bug] Corrected a use-after-free in isc_radix_remove().
(This function is not used in BIND, but could have
caused problems in programs linking to libisc.)
[RT #35870]

CHANGES
lib/isc/radix.c

diff --git a/CHANGES b/CHANGES
index 90dea36dd539f378064c25871118008a7cab9950..691d30b0a4d744b063f86ba786dc71b624b12556 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3826.  [bug]           Corrected a use-after-free in isc_radix_remove().
+                       (This function is not used in BIND, but could have
+                       caused problems in programs linking to libisc.)
+                       [RT #35870]
+
 3825.  [bug]           Address sign extension bug in isc_regex_validate.
                        [RT #35758]
 
index 82090d1fde9127239a08130b987497d47cf169e3..df26615fa9bfb0f2e74cdb48a85620775c7cc2b2 100644 (file)
@@ -634,12 +634,12 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) {
        if (node->r == NULL && node->l == NULL) {
                parent = node->parent;
                _deref_prefix(node->prefix);
-               isc_mem_put(radix->mctx, node, sizeof(*node));
-               radix->num_active_node--;
 
                if (parent == NULL) {
                        INSIST(radix->head == node);
                        radix->head = NULL;
+                       isc_mem_put(radix->mctx, node, sizeof(*node));
+                       radix->num_active_node--;
                        return;
                }
 
@@ -652,11 +652,13 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) {
                        child = parent->r;
                }
 
+               isc_mem_put(radix->mctx, node, sizeof(*node));
+               radix->num_active_node--;
+
                if (parent->prefix)
                        return;
 
                /* We need to remove parent too. */
-
                if (parent->parent == NULL) {
                        INSIST(radix->head == parent);
                        radix->head = child;
@@ -666,6 +668,7 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) {
                        INSIST(parent->parent->l == parent);
                        parent->parent->l = child;
                }
+
                child->parent = parent->parent;
                isc_mem_put(radix->mctx, parent, sizeof(*parent));
                radix->num_active_node--;
@@ -678,19 +681,23 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) {
                INSIST(node->l != NULL);
                child = node->l;
        }
+
        parent = node->parent;
        child->parent = parent;
 
        _deref_prefix(node->prefix);
-       isc_mem_put(radix->mctx, node, sizeof(*node));
-       radix->num_active_node--;
 
        if (parent == NULL) {
                INSIST(radix->head == node);
                radix->head = child;
+               isc_mem_put(radix->mctx, node, sizeof(*node));
+               radix->num_active_node--;
                return;
        }
 
+       isc_mem_put(radix->mctx, node, sizeof(*node));
+       radix->num_active_node--;
+
        if (parent->r == node) {
                parent->r = child;
        } else {