diff options
author | Guoqing Jiang <gqjiang@suse.com> | 2018-06-11 17:03:44 +0800 |
---|---|---|
committer | Jes Sorensen <jsorensen@fb.com> | 2018-06-11 06:35:41 -0400 |
commit | 898bd1ecefe6c72102f398680dcfef80e4de21c1 (patch) | |
tree | 070d1e320818fe345503a00356fbcf191e80247a | |
parent | 4a353e6ec48e35437b27978add6cd2cd015f2cfe (diff) | |
download | mdadm-898bd1ecefe6c72102f398680dcfef80e4de21c1.tar.gz |
Free map to avoid resource leak issues
1. There are some places which didn't free map as
discovered by coverity.
CID 289661 (#1 of 1): Resource leak (RESOURCE_LEAK)12. leaked_storage: Variable mapl going out of scope leaks the storage it points to.
CID 289619 (#3 of 3): Resource leak (RESOURCE_LEAK)63. leaked_storage: Variable map going out of scope leaks the storage it points to.
CID 289618 (#1 of 1): Resource leak (RESOURCE_LEAK)26. leaked_storage: Variable map going out of scope leaks the storage it points to.
CID 289607 (#1 of 1): Resource leak (RESOURCE_LEAK)41. leaked_storage: Variable map going out of scope leaks the storage it points to.
2. If we call map_by_* inside a loop, then map_free
should be called in the same loop, and it is better
to set map to NULL after free.
3. And map_unlock is always called with map_lock,
if we don't call map_remove before map_unlock,
then the memory (allocated by map_lock -> map_read
-> map_add -> xmalloc) could be leaked. So we
need to free it in map_unlock as well.
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-rw-r--r-- | Assemble.c | 2 | ||||
-rw-r--r-- | Detail.c | 2 | ||||
-rw-r--r-- | Incremental.c | 4 | ||||
-rw-r--r-- | config.c | 3 | ||||
-rw-r--r-- | mapfile.c | 2 | ||||
-rw-r--r-- | mdadm.c | 2 |
6 files changed, 13 insertions, 2 deletions
@@ -1851,8 +1851,8 @@ try_again: if (rv == 1 && !pre_exist) ioctl(mdfd, STOP_ARRAY, NULL); free(devices); - map_unlock(&map); out: + map_unlock(&map); if (rv == 0) { wait_for(chosen_name, mdfd); close(mdfd); @@ -263,6 +263,7 @@ int Detail(char *dev, struct context *c) if (st->ss->export_detail_super) st->ss->export_detail_super(st); + map_free(map); } else { struct map_ent *mp, *map = NULL; char nbuf[64]; @@ -277,6 +278,7 @@ int Detail(char *dev, struct context *c) print_escape(mp->path+8); putchar('\n'); } + map_free(map); } if (sra) { struct mdinfo *mdi; diff --git a/Incremental.c b/Incremental.c index 0beab16..0c5698e 100644 --- a/Incremental.c +++ b/Incremental.c @@ -1413,6 +1413,7 @@ restart: sysfs_free(sra); } } + map_free(mapl); return rv; } @@ -1587,6 +1588,8 @@ static int Incremental_container(struct supertype *st, char *devname, assemble_container_content(st, mdfd, ra, c, chosen_name, &result); + map_free(map); + map = NULL; close(mdfd); } if (c->export && result) { @@ -1663,6 +1666,7 @@ static int Incremental_container(struct supertype *st, char *devname, close(sfd); } domain_free(domains); + map_free(map); return 0; } @@ -181,9 +181,10 @@ struct mddev_dev *load_containers(void) } d->next = rv; rv = d; + map_free(map); + map = NULL; } free_mdstat(mdstat); - map_free(map); return rv; } @@ -143,6 +143,8 @@ void map_unlock(struct map_ent **melp) unlink(mapname[2]); fclose(lf); } + if (*melp) + map_free(*melp); lf = NULL; } @@ -1885,6 +1885,8 @@ static int misc_scan(char devmode, struct context *c) else rv |= WaitClean(name, c->verbose); put_md_name(name); + map_free(map); + map = NULL; } } free_mdstat(ms); |