[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Tue May 17 02:50:02 MDT 2011


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 <metze at samba.org>
Date:   Tue May 17 08:50:45 2011 +0200

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

commit 38633c9f0b7f86673f08903999583ad5b62c3548
Author: Stefan Metzmacher <metze at 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 <metze at 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


More information about the samba-cvs mailing list