summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuoqing Jiang <gqjiang@suse.com>2018-06-11 17:03:44 +0800
committerJes Sorensen <jsorensen@fb.com>2018-06-11 06:35:41 -0400
commit898bd1ecefe6c72102f398680dcfef80e4de21c1 (patch)
tree070d1e320818fe345503a00356fbcf191e80247a
parent4a353e6ec48e35437b27978add6cd2cd015f2cfe (diff)
downloadmdadm-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.c2
-rw-r--r--Detail.c2
-rw-r--r--Incremental.c4
-rw-r--r--config.c3
-rw-r--r--mapfile.c2
-rw-r--r--mdadm.c2
6 files changed, 13 insertions, 2 deletions
diff --git a/Assemble.c b/Assemble.c
index 32e6f6ff..5a907c14 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -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);
diff --git a/Detail.c b/Detail.c
index 860241ce..b3e857a7 100644
--- a/Detail.c
+++ b/Detail.c
@@ -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 0beab163..0c5698ee 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;
}
diff --git a/config.c b/config.c
index 48e02788..e14eae0c 100644
--- a/config.c
+++ b/config.c
@@ -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;
}
diff --git a/mapfile.c b/mapfile.c
index f3c8191e..a5025563 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -143,6 +143,8 @@ void map_unlock(struct map_ent **melp)
unlink(mapname[2]);
fclose(lf);
}
+ if (*melp)
+ map_free(*melp);
lf = NULL;
}
diff --git a/mdadm.c b/mdadm.c
index 5afe4155..1cf5c189 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -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);