The branch, master has been updated
       via  df2cb2f talloc: splitout _talloc_free_children_internal()
       via  38633c9 talloc: fixed a use after free error in 
talloc_free_children()
       via  f3b855d talloc: use _talloc_free_internal() in 
talloc_free_children()
      from  37b2130 talloc: test talloc_steal out of a talloc_pool

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit df2cb2f672569e5d113fe2e77fdc1ee16c8b646d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue May 17 08:50:45 2011 +0200

    talloc: splitout _talloc_free_children_internal()
    
    metze
    
    Autobuild-User: Stefan Metzmacher <me...@samba.org>
    Autobuild-Date: Tue May 17 10:49:13 CEST 2011 on sn-devel-104

commit 38633c9f0b7f86673f08903999583ad5b62c3548
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Apr 8 12:30:46 2011 +0200

    talloc: fixed a use after free error in talloc_free_children()
    
    This is similar to commit 6f51a1f45bf4de062cce7a562477e8140630a53d.
    
    metze

commit f3b855d2ff9576715afe50d75678829c6bc0842d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Apr 8 12:27:05 2011 +0200

    talloc: use _talloc_free_internal() in talloc_free_children()
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/talloc/talloc.c |   94 +++++++++++++++++++++++---------------------------
 1 files changed, 43 insertions(+), 51 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 9553405..4700aa9 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -768,6 +768,10 @@ static inline void _talloc_free_poolmem(struct 
talloc_chunk *tc,
        }
 }
 
+static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
+                                                 void *ptr,
+                                                 const char *location);
+
 /* 
    internal talloc_free call
 */
@@ -838,41 +842,7 @@ static inline int _talloc_free_internal(void *ptr, const 
char *location)
 
        tc->flags |= TALLOC_FLAG_LOOP;
 
-       while (tc->child) {
-               /* we need to work out who will own an abandoned child
-                  if it cannot be freed. In priority order, the first
-                  choice is owner of any remaining reference to this
-                  pointer, the second choice is our parent, and the
-                  final choice is the null context. */
-               void *child = TC_PTR_FROM_CHUNK(tc->child);
-               const void *new_parent = null_context;
-               struct talloc_chunk *old_parent = NULL;
-               if (unlikely(tc->child->refs)) {
-                       struct talloc_chunk *p = 
talloc_parent_chunk(tc->child->refs);
-                       if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-               }
-               /* finding the parent here is potentially quite
-                  expensive, but the alternative, which is to change
-                  talloc to always have a valid tc->parent pointer,
-                  makes realloc more expensive where there are a
-                  large number of children.
-
-                  The reason we need the parent pointer here is that
-                  if _talloc_free_internal() fails due to references
-                  or a failing destructor we need to re-parent, but
-                  the free call can invalidate the prev pointer.
-               */
-               if (new_parent == null_context && (tc->child->refs || 
tc->child->destructor)) {
-                       old_parent = talloc_parent_chunk(ptr);
-               }
-               if (unlikely(_talloc_free_internal(child, location) == -1)) {
-                       if (new_parent == null_context) {
-                               struct talloc_chunk *p = old_parent;
-                               if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-                       }
-                       _talloc_steal_internal(new_parent, child);
-               }
-       }
+       _talloc_free_children_internal(tc, ptr, location);
 
        tc->flags |= TALLOC_FLAG_FREE;
 
@@ -1264,21 +1234,10 @@ _PUBLIC_ void *talloc_init(const char *fmt, ...)
        return ptr;
 }
 
-/*
-  this is a replacement for the Samba3 talloc_destroy_pool functionality. It
-  should probably not be used in new code. It's in here to keep the talloc
-  code consistent across Samba 3 and 4.
-*/
-_PUBLIC_ void talloc_free_children(void *ptr)
+static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
+                                                 void *ptr,
+                                                 const char *location)
 {
-       struct talloc_chunk *tc;
-
-       if (unlikely(ptr == NULL)) {
-               return;
-       }
-
-       tc = talloc_chunk_from_ptr(ptr);
-
        while (tc->child) {
                /* we need to work out who will own an abandoned child
                   if it cannot be freed. In priority order, the first
@@ -1287,13 +1246,28 @@ _PUBLIC_ void talloc_free_children(void *ptr)
                   final choice is the null context. */
                void *child = TC_PTR_FROM_CHUNK(tc->child);
                const void *new_parent = null_context;
+               struct talloc_chunk *old_parent = NULL;
                if (unlikely(tc->child->refs)) {
                        struct talloc_chunk *p = 
talloc_parent_chunk(tc->child->refs);
                        if (p) new_parent = TC_PTR_FROM_CHUNK(p);
                }
-               if (unlikely(talloc_free(child) == -1)) {
+               /* finding the parent here is potentially quite
+                  expensive, but the alternative, which is to change
+                  talloc to always have a valid tc->parent pointer,
+                  makes realloc more expensive where there are a
+                  large number of children.
+
+                  The reason we need the parent pointer here is that
+                  if _talloc_free_internal() fails due to references
+                  or a failing destructor we need to re-parent, but
+                  the free call can invalidate the prev pointer.
+               */
+               if (new_parent == null_context && (tc->child->refs || 
tc->child->destructor)) {
+                       old_parent = talloc_parent_chunk(ptr);
+               }
+               if (unlikely(_talloc_free_internal(child, location) == -1)) {
                        if (new_parent == null_context) {
-                               struct talloc_chunk *p = 
talloc_parent_chunk(ptr);
+                               struct talloc_chunk *p = old_parent;
                                if (p) new_parent = TC_PTR_FROM_CHUNK(p);
                        }
                        _talloc_steal_internal(new_parent, child);
@@ -1301,6 +1275,24 @@ _PUBLIC_ void talloc_free_children(void *ptr)
        }
 }
 
+/*
+  this is a replacement for the Samba3 talloc_destroy_pool functionality. It
+  should probably not be used in new code. It's in here to keep the talloc
+  code consistent across Samba 3 and 4.
+*/
+_PUBLIC_ void talloc_free_children(void *ptr)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       _talloc_free_children_internal(tc, ptr, __location__);
+}
+
 /* 
    Allocate a bit of memory as a child of an existing pointer
 */


-- 
Samba Shared Repository

Reply via email to