From 05b54cc259645f69e14de2703724c284ed25838c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 22 Jun 2018 16:25:10 +0200 Subject: [PATCH] talloc_stack: Call talloc destructors while frame is still around This fixes "samba-tool ntacl set -d10" Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Sat Jun 23 04:56:44 CEST 2018 on sn-devel-144 --- lib/util/talloc_stack.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) 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; -- 2.34.1