Hello,

attached patch proposes solution for leaking memory when non-existing netgroup 
is looked up.

1st patch is just for testing - just call 'pkill -SIGUSR1 sssd_nss' and talloc 
report will be generated in /tmp/sssd_nss_talloc_report_full.

For details about the bug please see commit message in 2nd patch.

User who reported the bug confirmed that so far it seems that memory leak has 
been fixed and he didn't report any side effects.

Thanks!
>From abbf720b832beb6d04f909f598e7114a19f72a03 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <prei...@redhat.com>
Date: Wed, 30 Sep 2015 07:54:31 -0400
Subject: [PATCH 1/2] talloc_report for nss responder

---
 src/responder/nss/nsssrv.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index d8eff7968c4929663412aa56d08414689b921a22..79ca9ba89d49a5fd4ee3389e0f881b1a01f9c7a9 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -403,6 +403,20 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn,
     /* nss_shutdown(rctx); */
 }
 
+static void signal_nss_talloc_report(struct tevent_context *ev,
+                                     struct tevent_signal *se,
+                                     int signum,
+                                     int count,
+                                     void *siginfo,
+                                     void *private_data)
+{
+    FILE *f = fopen("/tmp/sssd_nss_talloc_report_full", "w");
+    if (f != NULL) {
+        talloc_report_full(NULL, f);
+        fclose(f);
+    }
+}
+
 int nss_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb)
@@ -417,6 +431,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     int hret;
     int fd_limit;
 
+    talloc_enable_leak_report_full();
+
     nss_cmds = get_nss_cmds();
 
     ret = sss_process_init(mem_ctx, ev, cdb,
@@ -558,6 +574,16 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
+    /* Handle SIGUSR1 to force offline behavior */
+    BlockSignals(false, SIGUSR1);
+    struct tevent_signal *tes;
+    tes = tevent_add_signal(rctx->ev, rctx, SIGUSR1, 0,
+                            signal_nss_talloc_report, rctx);
+    if (tes == NULL) {
+        ret = EIO;
+        goto fail;
+    }
+
     DEBUG(SSSDBG_TRACE_FUNC, "NSS Initialization complete\n");
 
     return EOK;
-- 
2.4.3

>From 0c05cef940b8a8650537056db4ade09b0b6a6fa6 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <prei...@redhat.com>
Date: Tue, 10 Nov 2015 10:56:56 -0500
Subject: [PATCH 2/2] NSS: Fix memory leak netgroup

If netgroup cannot be found in setnetgrent_retry() function
set_netgroup_entry() is called which steals getent_ctx directly to
nss_ctx->netgroups.
Subsequently function lookup_netgr_step() is called that (in case of
nenexisting group) will call create_negcache_netgr() which creates
a new dummy object to serve as negative cache. While doing so it calls
again set_netgroup_entry() for the same netgroup and it calls
hash_enter.

hash_enter will remove previously hashed entry for netgroup (created in
setnetgrent_retry()) from hash table but it won't be freed and thus it
leaks.

This patch sets netgroup lifetime for netgroups allocated in
setnetgrent_retry().

Resolves:
https://fedorahosted.org/sssd/ticket/2865
---
 src/responder/nss/nsssrv_netgroup.c | 38 ++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 9a78c1119c2f4e06e43ebec29ace775adc997e08..f3e64c1fa910ef400d2b5af38785faf08b7e6eff 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -31,6 +31,26 @@
 #include "confdb/confdb.h"
 #include "db/sysdb.h"
 
+static void set_netgr_lifetime(uint32_t lifetime,
+                               struct setent_step_ctx *step_ctx,
+                               struct getent_ctx *netgr);
+
+static uint32_t get_netgr_lifetime(int cache_refresh_percent,
+                                   uint32_t netgroup_timeout)
+{
+    uint32_t lifetime;
+
+    if (cache_refresh_percent != 0) {
+        lifetime = netgroup_timeout * (cache_refresh_percent / 100.0f);
+    } else {
+        lifetime = netgroup_timeout;
+    }
+
+    if (lifetime < 10) lifetime = 10;
+
+    return lifetime;
+}
+
 static errno_t get_netgroup_entry(struct nss_ctx *nctx,
                                   char *name,
                                   struct getent_ctx **netgr)
@@ -315,6 +335,8 @@ static errno_t setnetgrent_retry(struct tevent_req *req)
         }
         /* Will return control below */
     } else if (ret == ENOENT) {
+        uint32_t lifetime;
+
         /* This is the first attempt to request this netgroup
          */
         state->netgr = talloc_zero(nctx, struct getent_ctx);
@@ -373,6 +395,11 @@ static errno_t setnetgrent_retry(struct tevent_req *req)
             goto done;
         }
 
+        lifetime = get_netgr_lifetime(nctx->cache_refresh_percent,
+                                      dctx->domain->netgroup_timeout);
+
+        set_netgr_lifetime(lifetime, step_ctx, state->netgr);
+
         ret = lookup_netgr_step(step_ctx);
         switch (ret) {
         case EOK:
@@ -597,13 +624,10 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
                   name, dom->name);
         netgr->ready = true;
         netgr->found = true;
-        if (step_ctx->nctx->cache_refresh_percent) {
-            lifetime = dom->netgroup_timeout *
-                (step_ctx->nctx->cache_refresh_percent / 100.0);
-        } else {
-            lifetime = dom->netgroup_timeout;
-        }
-        if (lifetime < 10) lifetime = 10;
+
+        lifetime = get_netgr_lifetime(step_ctx->nctx->cache_refresh_percent,
+                                  step_ctx->dctx->domain->netgroup_timeout);
+
         set_netgr_lifetime(lifetime, step_ctx, netgr);
 
         ret = EOK;
-- 
2.4.3

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org

Reply via email to