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