summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2018-06-22 16:25:10 +0200
committerJeremy Allison <jra@samba.org>2018-06-23 04:56:44 +0200
commit05b54cc259645f69e14de2703724c284ed25838c (patch)
tree7e9a3ee211a0e6f1bfbfe5fbeacb422aa216069f /lib
parentf75e8f58cd2390c092631803d333adadb475306a (diff)
downloadsamba-05b54cc259645f69e14de2703724c284ed25838c.tar.gz
talloc_stack: Call talloc destructors while frame is still around
This fixes "samba-tool ntacl set -d10" Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Sat Jun 23 04:56:44 CEST 2018 on sn-devel-144
Diffstat (limited to 'lib')
-rw-r--r--lib/util/talloc_stack.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index 9c72c801197..4971150e0d5 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -94,6 +94,7 @@ static int talloc_pop(TALLOC_CTX *frame)
{
struct talloc_stackframe *ts =
(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+ size_t blocks;
int i;
/* Catch lazy frame-freeing. */
@@ -107,6 +108,34 @@ static int talloc_pop(TALLOC_CTX *frame)
#endif
}
+ for (i=0; i<10; i++) {
+
+ /*
+ * We have to free our children first, calling all
+ * destructors. If a destructor hanging deeply off
+ * "frame" uses talloc_tos() itself while freeing the
+ * toplevel frame, we panic because that nested
+ * talloc_tos() in the destructor does not find a
+ * stackframe anymore.
+ *
+ * Do it in a loop up to 10 times as the destructors
+ * might use more of talloc_tos().
+ */
+
+ talloc_free_children(frame);
+
+ blocks = talloc_total_blocks(frame);
+ if (blocks == 1) {
+ break;
+ }
+ }
+
+ if (blocks != 1) {
+ DBG_WARNING("Left %zu blocks after %i "
+ "talloc_free_children(frame) calls\n",
+ blocks, i);
+ }
+
for (i=ts->talloc_stacksize-1; i>0; i--) {
if (frame == ts->talloc_stack[i]) {
break;