summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Coffman <kwc@citi.umich.edu>2007-02-08 17:27:14 -0500
committerNeil Brown <neilb@suse.de>2007-02-09 11:42:19 +1100
commite54fb292fcd9253743fc17ba0af26dcbb0723a5d (patch)
tree57e5f611ba448c995bfc14860c0e66bc75ba1dfd
parent2344b8edd958a1089fb19e985a735b41f6e7677e (diff)
downloadnfs-utils-e54fb292fcd9253743fc17ba0af26dcbb0723a5d.tar.gz
nfs-utils-e54fb292fcd9253743fc17ba0af26dcbb0723a5d.tar.xz
nfs-utils-e54fb292fcd9253743fc17ba0af26dcbb0723a5d.zip
Fix memory leak in idmapd.
Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Kevin Coffman <kwc@citi.umich.edu> There is a pretty nasty memory leak in idmapd in dirscancb(). Some of our customers have reported that idmapd can eat gigabytes of memory on machines with a large number of mounts and unmounts and a long uptime. That function uses scandir(), which malloc's an array of strings, but dirscancb() never frees the strings or the array. The following patch should correct this, but I've not yet tested it on 1.0.10 (only on the RHEL4 1.0.6 version). Still, the code is very similar and I'm fairly certain the problem exists in both versions. Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--utils/idmapd/idmapd.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
index 19bf7a6..cbb0b6a 100644
--- a/utils/idmapd/idmapd.c
+++ b/utils/idmapd/idmapd.c
@@ -464,7 +464,7 @@ dirscancb(int fd, short which, void *data)
goto next;
if ((ic = calloc(1, sizeof(*ic))) == NULL)
- return;
+ goto out;
strlcpy(ic->ic_clid, ents[i]->d_name + 4,
sizeof(ic->ic_clid));
path[0] = '\0';
@@ -474,7 +474,7 @@ dirscancb(int fd, short which, void *data)
if ((ic->ic_dirfd = open(path, O_RDONLY, 0)) == -1) {
idmapd_warn("dirscancb: open(%s)", path);
free(ic);
- return;
+ goto out;
}
strlcat(path, "/idmap", sizeof(path));
@@ -486,7 +486,7 @@ dirscancb(int fd, short which, void *data)
if (nfsopen(ic) == -1) {
close(ic->ic_dirfd);
free(ic);
- return;
+ goto out;
}
ic->ic_id = "Client";
@@ -512,6 +512,11 @@ dirscancb(int fd, short which, void *data)
} else
ic->ic_scanned = 0;
}
+
+out:
+ for (i = 0; i < nent; i++)
+ free(ents[i]);
+ free(ents);
return;
}