diff options
author | Michael Adam <obnox@samba.org> | 2011-12-22 18:09:36 +0100 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2011-12-23 17:39:00 +0100 |
commit | 3dab0c9b0ba7ce6f15c9a9c3fb45188edf8ce307 (patch) | |
tree | e86ce508ca19dbb939d11da6e01926e762c5f1e4 | |
parent | 6e42e03b57769c0cc6ce7cc723af93d5a6372918 (diff) | |
download | samba-3dab0c9b0ba7ce6f15c9a9c3fb45188edf8ce307.tar.gz samba-3dab0c9b0ba7ce6f15c9a9c3fb45188edf8ce307.tar.xz samba-3dab0c9b0ba7ce6f15c9a9c3fb45188edf8ce307.zip |
rb_tree: fix possible access-after-free-error in trbt_traversearray32_node
When the traverse callback frees the current node, the traverse of the
rbtree can fail (the next node->right fails since node is not there any more...).
This is fixed by introducing variables to store the right (and left)
pointers before the callback is called.
(This used to be ctdb commit 8b0caaeed154d26c67a73659d3bbbdd63b21be11)
-rw-r--r-- | ctdb/common/rb_tree.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/ctdb/common/rb_tree.c b/ctdb/common/rb_tree.c index 8458c510be..bff7c5a4c4 100644 --- a/ctdb/common/rb_tree.c +++ b/ctdb/common/rb_tree.c @@ -921,9 +921,12 @@ trbt_traversearray32_node(trbt_node_t *node, uint32_t keylen, int (*callback)(void *param, void *data), void *param) { - if (node->left) { + trbt_node_t *left = node->left; + trbt_node_t *right = node->right; + + if (left) { int ret; - ret = trbt_traversearray32_node(node->left, keylen, callback, param); + ret = trbt_traversearray32_node(left, keylen, callback, param); if (ret != 0) { return ret; } @@ -949,10 +952,10 @@ trbt_traversearray32_node(trbt_node_t *node, uint32_t keylen, } } - if (node->right) { + if (right) { int ret; - ret = trbt_traversearray32_node(node->right, keylen, callback, param); + ret = trbt_traversearray32_node(right, keylen, callback, param); if (ret != 0) { return ret; } |