diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-09-14 03:44:10 -0700 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-09-14 09:41:52 -0700 |
commit | 33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d (patch) | |
tree | bb19988febdc66a274a181776fab0481b16fa87f /source4 | |
parent | 3cf73dfdbdd33189e0f9f22e0e494962376f9b86 (diff) | |
download | samba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.tar.gz samba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.tar.bz2 samba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.zip |
s4-repl: fixed a memory error handling linked attributes
We could get a double free with multiple linked attributes in a
message
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 3afe11ae51..b9323b912b 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -47,6 +47,7 @@ #include "lib/util/dlinklist.h" struct replmd_private { + TALLOC_CTX *la_ctx; struct la_entry *la_list; uint32_t num_ncs; struct nc_entry { @@ -1896,13 +1897,10 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct for (i=0; i<ar->objs->linked_attributes_count; i++) { struct la_entry *la_entry; - if (replmd_private->la_list) { - la_entry = talloc(replmd_private->la_list, - struct la_entry); - } else { - la_entry = talloc(replmd_private, - struct la_entry); + if (replmd_private->la_ctx == NULL) { + replmd_private->la_ctx = talloc_new(replmd_private); } + la_entry = talloc(replmd_private->la_ctx, struct la_entry); if (la_entry == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; @@ -2108,8 +2106,9 @@ static int replmd_start_transaction(struct ldb_module *module) int i; struct replmd_private *replmd_private = talloc_get_type(ldb_module_get_private(module), struct replmd_private); - talloc_free(replmd_private->la_list); + talloc_free(replmd_private->la_ctx); replmd_private->la_list = NULL; + replmd_private->la_ctx = NULL; for (i=0; i<replmd_private->num_ncs; i++) { replmd_private->ncs[i].mod_usn = 0; @@ -2138,14 +2137,14 @@ static int replmd_prepare_commit(struct ldb_module *module) prev = la->prev; DLIST_REMOVE(replmd_private->la_list, la); ret = replmd_process_linked_attribute(module, la); - talloc_free(la); if (ret != LDB_SUCCESS) { return ret; } } - talloc_free(replmd_private->la_list); + talloc_free(replmd_private->la_ctx); replmd_private->la_list = NULL; + replmd_private->la_ctx = NULL; /* possibly change @REPLCHANGED */ ret = replmd_notify_store(module); @@ -2160,8 +2159,9 @@ static int replmd_del_transaction(struct ldb_module *module) { struct replmd_private *replmd_private = talloc_get_type(ldb_module_get_private(module), struct replmd_private); - talloc_free(replmd_private->la_list); + talloc_free(replmd_private->la_ctx); replmd_private->la_list = NULL; + replmd_private->la_ctx = NULL; return ldb_next_del_trans(module); } |