Module: sip-router Branch: master Commit: 47daa2e1174376fa94b858ea9473b868161e7341 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=47daa2e1...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Tue Jan 4 11:14:30 2011 +0100
cfg framework: mem leak in del_group_inst is corrected
cfg_del_group_inst() did not free the strings that were set within the group instance. When the group instance was deleted, the strings left allocated.
---
cfg/cfg_ctx.c | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c index b23925c..5fe2dc6 100644 --- a/cfg/cfg_ctx.c +++ b/cfg/cfg_ctx.c @@ -1521,6 +1521,8 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id) cfg_block_t *block = NULL; void **replaced = NULL; cfg_group_inst_t *new_array = NULL, *group_inst; + cfg_mapping_t *var; + int i, num;
/* verify the context even if we do not need it now to make sure that a cfg driver has called the function @@ -1571,13 +1573,41 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id) /* prepare the array of the replaced strings, and replaced group instances, they will be freed when the old block is freed */ - replaced = (void **)shm_malloc(sizeof(void *) * 2); + + /* count the number of strings that has to be freed */ + num = 0; + for (i = 0; i < group->num; i++) { + var = &group->mapping[i]; + if (CFG_VAR_TEST(group_inst, var) + && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR)) + && (*(char **)(group_inst->vars + var->offset) != NULL) + ) + num++; + } + + replaced = (void **)shm_malloc(sizeof(void *) * (num + 2)); if (!replaced) { LOG(L_ERR, "ERROR: cfg_del_group_inst(): not enough shm memory\n"); goto error; } - replaced[0] = CFG_GROUP_META(*cfg_global, group)->array; - replaced[1] = NULL; + + if (num) { + /* There was at least one string to free, go though the list again */ + num = 0; + for (i = 0; i < group->num; i++) { + var = &group->mapping[i]; + if (CFG_VAR_TEST(group_inst, var) + && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR)) + && (*(char **)(group_inst->vars + var->offset) != NULL) + ) { + replaced[num] = *(char **)(group_inst->vars + var->offset); + num++; + } + } + } + + replaced[num] = CFG_GROUP_META(*cfg_global, group)->array; + replaced[num+1] = NULL; } /* replace the global config with the new one */ cfg_install_global(block, replaced, NULL, NULL);