summaryrefslogtreecommitdiff
path: root/lib/talloc
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-07-27 12:02:35 -0400
committerAndrew Tridgell <tridge@samba.org>2011-07-29 18:17:44 +1000
commit52182a528117c4dd9624f64b34a873c0903ad70a (patch)
tree76f0860d6c2964942f9a9e70073cc78081c6c63b /lib/talloc
parent03f92508ef2ebb4e7790f612e3f833382c691051 (diff)
downloadsamba-52182a528117c4dd9624f64b34a873c0903ad70a.tar.gz
samba-52182a528117c4dd9624f64b34a873c0903ad70a.tar.bz2
samba-52182a528117c4dd9624f64b34a873c0903ad70a.zip
talloc: preserve context name on talloc_free_children()
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>
Diffstat (limited to 'lib/talloc')
-rw-r--r--lib/talloc/talloc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 4700aa99e8..a820ebf0ac 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -1282,6 +1282,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)) {
@@ -1290,7 +1291,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);
+ }
}
/*