The branch, master has been updated via 686825e... s4:registry - "patchfile" - initialise the data blobs via c5b9b25... s4:registry - "patchfile" - add more "talloc_free"s to save memory via 885a167... s4:registry - "util.c" - "reg_string_to_val" - consider always the return values via 6f7f16d... s4:registry - "patchfile_preg.c" - also here don't accumulate the memory usage via 93472b4... s4:registry - "patchfile_dotreg.c" - fix a memory leak via 5f24bfb... s4:registry - "patchfile" - add comments from b2f45f2... s3: Add "log writeable files on exit" parameter
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 686825e0255a106d7bc67fb6059cd3c1ddefe315 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 13:33:04 2010 +0100 s4:registry - "patchfile" - initialise the data blobs commit c5b9b25c714516555bb6832edb62a72b66268dd8 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 12:42:21 2010 +0100 s4:registry - "patchfile" - add more "talloc_free"s to save memory commit 885a167929c7f5409a6239705ef6142ecc014ff3 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 12:22:13 2010 +0100 s4:registry - "util.c" - "reg_string_to_val" - consider always the return values In some cases we didn't consider them. commit 6f7f16dc80000ccea582036dc58ce81ea9f078b0 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 12:15:19 2010 +0100 s4:registry - "patchfile_preg.c" - also here don't accumulate the memory usage Free always the unused stuff. commit 93472b41dedd8e30be8752c271f2b4bca392176a Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 12:00:57 2010 +0100 s4:registry - "patchfile_dotreg.c" - fix a memory leak Here we allocate memory on the "NULL" context through "reg_val_data_string" on each call of "set_value". So when we have written out the allocated data on the specified file descriptor we should immediately free this memory! Otherwise we may end up with a big memory consumption on big registry databases. commit 5f24bfb7b9419d4aac220adc038bd3776fc172e6 Author: Matthias Dieter Wallnöfer <mwallnoe...@yahoo.de> Date: Mon Mar 22 11:45:20 2010 +0100 s4:registry - "patchfile" - add comments Helps to understand when we need to generate the hive diffs. ----------------------------------------------------------------------- Summary of changes: source4/lib/registry/patchfile.c | 45 ++++++++++++++++++++++++++----- source4/lib/registry/patchfile_dotreg.c | 8 +++-- source4/lib/registry/patchfile_preg.c | 30 ++++++++++++++++++--- source4/lib/registry/util.c | 16 ++++++----- 4 files changed, 78 insertions(+), 21 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 6b08cf8..9a4c9a6 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -4,7 +4,7 @@ Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 - Copyright (C) Matthias Dieter Wallnöfer 2008 + Copyright (C) Matthias Dieter Wallnöfer 2008-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -175,7 +175,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, for(i = 0; i < new_num_values; i++) { const char *name; uint32_t type1, type2; - DATA_BLOB contents1, contents2; + DATA_BLOB contents1 = { NULL, 0 }, contents2 = { NULL, 0 }; error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &name, &type1, &contents1); @@ -202,19 +202,27 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } if (W_ERROR_IS_OK(error2) - && (data_blob_cmp(&contents1, &contents2) == 0) - && (type1 == type2)) + && (data_blob_cmp(&contents1, &contents2) == 0) + && (type1 == type2)) { + talloc_free(discard_const_p(char, name)); + talloc_free(contents1.data); + talloc_free(contents2.data); continue; + } callbacks->set_value(callback_data, path, name, type1, contents1); + + talloc_free(discard_const_p(char, name)); + talloc_free(contents1.data); + talloc_free(contents2.data); } /* Values that were deleted */ for (i = 0; i < old_num_values; i++) { const char *name; uint32_t type; - DATA_BLOB contents; + DATA_BLOB contents = { NULL, 0 }; error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, &type, &contents); @@ -231,8 +239,11 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, else error2 = WERR_BADFILE; - if (W_ERROR_IS_OK(error2)) + if (W_ERROR_IS_OK(error2)) { + talloc_free(discard_const_p(char, name)); + talloc_free(contents.data); continue; + } if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occurred while getting value by name: %s\n", @@ -242,6 +253,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } callbacks->del_value(callback_data, path, name); + + talloc_free(discard_const_p(char, name)); + talloc_free(contents.data); } talloc_free(mem_ctx); @@ -280,10 +294,16 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, continue; } + /* if "r1" is NULL (old hive) and "r2" isn't (new hive) then + * the hive doesn't exist yet and we have to generate an add + * diff */ if ((r1 == NULL) && (r2 != NULL)) { callbacks->add_key(callback_data, reg_predefined_keys[i].name); } + /* if "r1" isn't NULL (old hive) and "r2" is (new hive) then + * the hive shouldn't exist anymore and we have to generate a + * del diff */ if ((r1 != NULL) && (r2 == NULL)) { callbacks->del_key(callback_data, reg_predefined_keys[i].name); @@ -375,9 +395,12 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) return error; } *buf_ptr++ = '\\'; + talloc_free(tmp); } } + talloc_free(buf); + /* Add the key */ error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp); @@ -387,6 +410,8 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) key_name, win_errstr(error))); return error; } + talloc_free(tmp); + return WERR_OK; } @@ -428,6 +453,8 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, return error; } + talloc_free(tmp); + return WERR_OK; } @@ -452,6 +479,7 @@ static WERROR reg_diff_apply_del_value(void *_ctx, const char *key_name, return error; } + talloc_free(tmp); return WERR_OK; } @@ -461,7 +489,7 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *key; WERROR error; - const char* value_name; + const char *value_name; error = reg_open_key_abs(ctx, ctx, key_name, &key); @@ -480,8 +508,11 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) DEBUG(0, ("Error deleting value '%s'\n", value_name)); return error; } + talloc_free(discard_const_p(char, value_name)); } + talloc_free(key); + return WERR_OK; } diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 3b57089..12f2f70 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -61,10 +61,12 @@ static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, uint32_t value_type, DATA_BLOB value) { struct dotreg_data *data = (struct dotreg_data *)_data; - + char *data_string = reg_val_data_string(NULL, data->iconv_convenience, + value_type, value); + W_ERROR_HAVE_NO_MEMORY(data_string); fdprintf(data->fd, "\"%s\"=%s:%s\n", - value_name, str_regtype(value_type), - reg_val_data_string(NULL, data->iconv_convenience, value_type, value)); + value_name, str_regtype(value_type), data_string); + talloc_free(data_string); return WERR_OK; } diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index d7b4bc3..c75b08d 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -88,15 +88,23 @@ static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) struct preg_data *data = (struct preg_data *)_data; char *parent_name; DATA_BLOB blob; + WERROR werr; parent_name = talloc_strndup(data->ctx, key_name, strrchr(key_name, '\\')-key_name); + W_ERROR_HAVE_NO_MEMORY(parent_name); blob.data = (uint8_t *)talloc_strndup(data->ctx, key_name+(strrchr(key_name, '\\')-key_name)+1, strlen(key_name)-(strrchr(key_name, '\\')-key_name)); + W_ERROR_HAVE_NO_MEMORY(blob.data); blob.length = strlen((char *)blob.data)+1; /* FIXME: These values should be accumulated to be written at done(). */ - return reg_preg_diff_set_value(data, parent_name, "**DeleteKeys", REG_SZ, blob); + werr = reg_preg_diff_set_value(data, parent_name, "**DeleteKeys", REG_SZ, blob); + + talloc_free(parent_name); + talloc_free(blob.data); + + return werr; } static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, @@ -105,25 +113,39 @@ static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, struct preg_data *data = (struct preg_data *)_data; char *val; DATA_BLOB blob; + WERROR werr; val = talloc_asprintf(data->ctx, "**Del.%s", value_name); - + W_ERROR_HAVE_NO_MEMORY(val); blob.data = (uint8_t *)talloc(data->ctx, uint32_t); + W_ERROR_HAVE_NO_MEMORY(blob.data); SIVAL(blob.data, 0, 0); blob.length = 4; - return reg_preg_diff_set_value(data, key_name, val, REG_DWORD, blob); + + werr = reg_preg_diff_set_value(data, key_name, val, REG_DWORD, blob); + + talloc_free(val); + talloc_free(blob.data); + + return werr; } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { struct preg_data *data = (struct preg_data *)_data; DATA_BLOB blob; + WERROR werr; blob.data = (uint8_t *)talloc(data->ctx, uint32_t); + W_ERROR_HAVE_NO_MEMORY(blob.data); SIVAL(blob.data, 0, 0); blob.length = 4; - return reg_preg_diff_set_value(data, key_name, "**DelVals.", REG_DWORD, blob); + werr = reg_preg_diff_set_value(data, key_name, "**DelVals.", REG_DWORD, blob); + + talloc_free(blob.data); + + return werr; } static WERROR reg_preg_diff_done(void *_data) diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 3c12899..b389ea4 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -146,24 +146,26 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, break; case REG_SZ: case REG_EXPAND_SZ: - convert_string_talloc_convenience(mem_ctx, - iconv_convenience, - CH_UNIX, CH_UTF16, - data_str, - strlen(data_str)+1, - (void **)&data->data, - &data->length, false); + return convert_string_talloc_convenience(mem_ctx, + iconv_convenience, + CH_UNIX, CH_UTF16, + data_str, + strlen(data_str)+1, + (void **)&data->data, + &data->length, false); break; case REG_DWORD: case REG_DWORD_BIG_ENDIAN: { uint32_t tmp = strtol(data_str, NULL, 0); *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint32_t)); + if (data->data == NULL) return false; SIVAL(data->data, 0, tmp); } break; case REG_QWORD: { uint64_t tmp = strtoll(data_str, NULL, 0); *data = data_blob_talloc(mem_ctx, NULL, sizeof(uint64_t)); + if (data->data == NULL) return false; SBVAL(data->data, 0, tmp); } break; -- Samba Shared Repository