summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Zidek <mzidek@redhat.com>2013-03-06 16:46:32 +0100
committerJakub Hrozek <jhrozek@redhat.com>2013-08-09 12:07:30 +0200
commit6ed0eb3bf1b322a246aad6c3e02a7c3b4619d867 (patch)
treee8d1a5c1d049eaa2749d07c74152c83bcd06099a /src
parent26ef9fa37ef19709b214e230b4e4ee6d61120d30 (diff)
downloadsssd-6ed0eb3bf1b322a246aad6c3e02a7c3b4619d867.tar.gz
sssd-6ed0eb3bf1b322a246aad6c3e02a7c3b4619d867.tar.xz
sssd-6ed0eb3bf1b322a246aad6c3e02a7c3b4619d867.zip
File descriptor leak in nss responder.sssd-1.9.2-112.el6
File descriptors leaked every time sss_mmap_cache_reinit was called and also the old memory cache was still maped in memory (munmap was not called). This patch adds destructor for memory cache context to call close() and munmap() automaticly. https://fedorahosted.org/sssd/ticket/1826
Diffstat (limited to 'src')
-rw-r--r--src/responder/nss/nsssrv_mmap_cache.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 6cd359495..8cf27ca69 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -801,7 +801,7 @@ static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
errno = 0;
ret = unlink(mc_ctx->file);
- if (ret == -1) {
+ if (ret == -1 && errno != ENOENT) {
ret = errno;
DEBUG(SSSDBG_TRACE_FUNC, ("Failed to rm mmap file %s: %d(%s)\n",
mc_ctx->file, ret, strerror(ret)));
@@ -826,6 +826,7 @@ static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
DEBUG(SSSDBG_FATAL_FAILURE,
("Failed to lock file %s.\n", mc_ctx->file));
close(mc_ctx->fd);
+ mc_ctx->fd = -1;
/* Report on unlink failures but don't overwrite the errno
* from sss_br_lock_file
@@ -868,6 +869,36 @@ static void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status)
MC_LOWER_BARRIER(h);
}
+static int mc_ctx_destructor(struct sss_mc_ctx *mc_ctx)
+{
+ int ret;
+
+ /* Print debug message to logs if munmap() or close()
+ * fail but always return 0 */
+
+ if (mc_ctx->mmap_base != NULL) {
+ ret = munmap(mc_ctx->mmap_base, mc_ctx->mmap_size);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to unmap old memory cache file."
+ "[%d]: %s\n", ret, strerror(ret)));
+ }
+ }
+
+ if (mc_ctx->fd != -1) {
+ ret = close(mc_ctx->fd);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to close old memory cache file."
+ "[%d]: %s\n", ret, strerror(ret)));
+ }
+ }
+
+ return 0;
+}
+
errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
enum sss_mc_type type, size_t n_elem,
time_t timeout, struct sss_mc_ctx **mcc)
@@ -875,7 +906,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
struct sss_mc_ctx *mc_ctx = NULL;
unsigned int rseed;
int payload;
- int ret;
+ int ret, dret;
switch (type) {
case SSS_MC_PASSWD:
@@ -893,6 +924,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
return ENOMEM;
}
mc_ctx->fd = -1;
+ talloc_set_destructor(mc_ctx, mc_ctx_destructor);
mc_ctx->name = talloc_strdup(mc_ctx, name);
if (!mc_ctx->name) {
@@ -974,15 +1006,14 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
done:
if (ret) {
- if (mc_ctx && mc_ctx->mmap_base) {
- munmap(mc_ctx->mmap_base, mc_ctx->mmap_size);
- }
- if (mc_ctx && mc_ctx->fd != -1) {
- close(mc_ctx->fd);
- ret = unlink(mc_ctx->file);
- if (ret == -1) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to rm mmap file %s: %d(%s)\n",
- mc_ctx->file, ret, strerror(ret)));
+ /* Closing the file descriptor and ummaping the file
+ * from memory is done in the mc_ctx_destructor. */
+ if (mc_ctx && mc_ctx->file && mc_ctx->fd != -1) {
+ dret = unlink(mc_ctx->file);
+ if (dret == -1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file,
+ dret, strerror(dret)));
}
}
@@ -1030,13 +1061,7 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
timeout = (*mc_ctx)->valid_time_slot;
}
- ret = talloc_free(*mc_ctx);
- if (ret != 0) {
- /* This can happen only if destructor is associated with this
- * context */
- DEBUG(SSSDBG_MINOR_FAILURE, ("Destructor asociated with memory"
- " context failed.\n"));
- }
+ talloc_free(*mc_ctx);
/* make sure we do not leave a potentially freed pointer around */
*mc_ctx = NULL;