From b2c682e462f7f40cfaedc2314b547203996b7b2b Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Thu, 6 Jan 2011 15:29:24 +0000 Subject: [PATCH] Fix memory leak in filter creation error path If some allocation for peristent filter fails its memory reference was lost, fix it by calling filter's destructor. Fix log_error messages for failing allocation. --- WHATS_NEW | 1 + lib/commands/toolcontext.c | 7 +++++-- lib/filters/filter-persistent.c | 19 ++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 1a4dcc77d..7611c92d6 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.80 - ==================================== + Fix memory leak in filter creation error path. Add missing tests in _setup_task(). Fail poll daemon creation when lvmcache_init() fails. Return defined value for errors in _copy_percent() and _snap_percent(). diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index c4da38af6..479901657 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -708,6 +708,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache cache_dir ? : DEFAULT_CACHE_SUBDIR, cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) { log_error("Persistent cache filename too long."); + f3->destroy(f3); return 0; } } else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) && @@ -716,6 +717,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache cmd->system_dir, DEFAULT_CACHE_SUBDIR, DEFAULT_CACHE_FILE_PREFIX) < 0)) { log_error("Persistent cache filename too long."); + f3->destroy(f3); return 0; } @@ -723,8 +725,9 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache dev_cache = cache_file; if (!(f4 = persistent_filter_create(f3, dev_cache))) { - log_error("Failed to create persistent device filter"); - return 0; + log_verbose("Failed to create persistent device filter."); + f3->destroy(f3); + return_0; } /* Should we ever dump persistent filter state? */ diff --git a/lib/filters/filter-persistent.c b/lib/filters/filter-persistent.c index f3b1e05bd..3025e68f4 100644 --- a/lib/filters/filter-persistent.c +++ b/lib/filters/filter-persistent.c @@ -318,13 +318,16 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real, struct dev_filter *f = NULL; struct stat info; - if (!(pf = dm_zalloc(sizeof(*pf)))) - return_NULL; + if (!(pf = dm_zalloc(sizeof(*pf)))) { + log_error("Allocation of persistent filter failed."); + return NULL; + } - if (!(pf->file = dm_malloc(strlen(file) + 1))) - goto_bad; + if (!(pf->file = dm_strdup(file))) { + log_error("Filename duplication for persistent filter failed."); + goto bad; + } - strcpy(pf->file, file); pf->real = real; if (!(_init_hash(pf))) { @@ -332,8 +335,10 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real, goto bad; } - if (!(f = dm_malloc(sizeof(*f)))) - goto_bad; + if (!(f = dm_malloc(sizeof(*f)))) { + log_error("Allocation of device filter for persistent filter failed."); + goto bad; + } /* Only merge cache file before dumping it if it changed externally. */ if (!stat(pf->file, &info)) -- 2.43.5