]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
talloc: preserve context name on talloc_free_children()
authorSimo Sorce <idra@samba.org>
Wed, 27 Jul 2011 16:02:35 +0000 (12:02 -0400)
committerKarolin Seeger <kseeger@samba.org>
Fri, 16 Sep 2011 18:41:26 +0000 (20:41 +0200)
Otherwise tc->name will end up pointing to garbage when it is not
set to a const but rather to a string allocate as child of the context itself.

Signed-off-by: Andrew Tridgell <tridge@samba.org>
(cherry picked from commit 52182a528117c4dd9624f64b34a873c0903ad70a)
(cherry picked from commit 99495ea4d28de530fedc11c94d36bc304cf9ae4a)

lib/talloc/talloc.c

index a0217d14e933eaf2e65fcc93f1455181c33e46ef..19e6a37f2c3bf7882f64e7589eb893c0bf5cea1d 100644 (file)
@@ -1270,6 +1270,7 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
 */
 _PUBLIC_ void talloc_free_children(void *ptr)
 {
+       struct talloc_chunk *tc_name = NULL;
        struct talloc_chunk *tc;
 
        if (unlikely(ptr == NULL)) {
@@ -1278,7 +1279,29 @@ _PUBLIC_ void talloc_free_children(void *ptr)
 
        tc = talloc_chunk_from_ptr(ptr);
 
+       /* we do not want to free the context name if it is a child .. */
+       if (likely(tc->child)) {
+               for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
+                       if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
+               }
+               if (tc_name) {
+                       _TLIST_REMOVE(tc->child, tc_name);
+                       if (tc->child) {
+                               tc->child->parent = tc;
+                       }
+               }
+       }
+
        _talloc_free_children_internal(tc, ptr, __location__);
+
+       /* .. so we put it back after all other children have been freed */
+       if (tc_name) {
+               if (tc->child) {
+                       tc->child->parent = NULL;
+               }
+               tc_name->parent = tc;
+               _TLIST_ADD(tc->child, tc_name);
+       }
 }
 
 /*