summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2011-12-22 18:09:36 +0100
committerMichael Adam <obnox@samba.org>2011-12-23 17:39:00 +0100
commit3dab0c9b0ba7ce6f15c9a9c3fb45188edf8ce307 (patch)
treee86ce508ca19dbb939d11da6e01926e762c5f1e4
parent6e42e03b57769c0cc6ce7cc723af93d5a6372918 (diff)
downloadsamba-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.c11
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;
}