eio__scandir() leaks memory when opendir() returns NULL. It sets req->result == -1 but doesn't free the memory it allocates.
Attached are two patches (different takes, same solution) that fix that: one tries to be brief, the other minimally intrusive. The brief one has a return statement in the middle of the function. Not all people like that, hence the two takes. Pick the one you like best. Apropos, two things I noticed about eio__scandir() is that it: 1. doesn't set req->errorno when opendir() fails (both patches fix that), and 2. uses readdir(), which is not guaranteed to be thread-safe. glibc wraps it in a mutex and I think sunos's libc does so too but readdir_r() is what should be used, really.
From a2a801cacd2c26ec7bf9bce00cee68f0317bc2c6 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis <i...@bnoordhuis.nl> Date: Mon, 12 Sep 2011 16:29:56 +0200 Subject: [PATCH] Fix memory leak in eio__scandir() --- eio.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/eio.c b/eio.c index d59db3e..c62535c 100644 --- a/eio.c +++ b/eio.c @@ -1737,6 +1737,9 @@ eio__scandir (eio_req *req, etp_worker *self) dirp = opendir (req->ptr1); #endif + if (!dirp) + req->errorno = errno; + if (req->flags & EIO_FLAG_PTR1_FREE) free (req->ptr1); @@ -1929,6 +1932,15 @@ eio__scandir (eio_req *req, etp_worker *self) } #endif } + + if (req->result == -1) + { + req->flags &= ~(EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE); + free(req->ptr1); + free(req->ptr2); + req->ptr1 = NULL; + req->ptr2 = NULL; + } } /*****************************************************************************/ -- 1.7.6
From b2347858500431caff9cb66491cab10e9c6302c3 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis <i...@bnoordhuis.nl> Date: Mon, 12 Sep 2011 17:14:46 +0200 Subject: [PATCH] Fix memory leak in eio__scandir() --- eio.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/eio.c b/eio.c index d59db3e..6add505 100644 --- a/eio.c +++ b/eio.c @@ -1738,7 +1738,17 @@ eio__scandir (eio_req *req, etp_worker *self) #endif if (req->flags & EIO_FLAG_PTR1_FREE) - free (req->ptr1); + { + req->flags &= ~EIO_FLAG_PTR1_FREE; + free (req->ptr1); + req->ptr1 = NULL; + } + + if (!dirp) + { + req->errorno = errno; + return; + } req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; -- 1.7.6
_______________________________________________ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev