]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
Real memeory leak(buildup) issue in loadparm.
authorHemanth Thummala <hemanth.thummala@nutanix.com>
Tue, 16 Feb 2016 22:44:38 +0000 (14:44 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 17 Feb 2016 21:30:25 +0000 (22:30 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11740

As part of reload services, unused service ptr structures are getting
unloaded without actually freeingup the memory associated to them.

Made changes to freeup those allocations on unload. On reload, reuse the
slots in ServicePtr global array instead of extending the array with
holes.

Also we should mark shares like IPC$ as auto loaded as they never be
exposed to users.

Signed-off-by: Hemanth Thummala <hemanth.thummala@nutanix.com>
Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Feb 17 22:30:25 CET 2016 on sn-devel-144

source3/param/loadparm.c

index 7c3195bc3072acbf36b426f798aeadea3cac7445..50b29e323849e5239a13556f1c8b8335e075510a 100644 (file)
@@ -93,8 +93,11 @@ static struct smbconf_csn conf_last_csn;
 static int config_backend = CONFIG_BACKEND_FILE;
 
 /* some helpful bits */
-#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
-#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
+#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
+                       (ServicePtrs != NULL) && \
+                      (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
+#define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
+                  ServicePtrs[i]->valid)
 
 #define USERSHARE_VALID 1
 #define USERSHARE_PENDING_DELETE 2
@@ -1358,7 +1361,7 @@ static void free_service_byindex(int idx)
        }
 
        free_service(ServicePtrs[idx]);
-       talloc_free_children(ServicePtrs[idx]);
+       TALLOC_FREE(ServicePtrs[idx]);
 }
 
 /***************************************************************************
@@ -1380,20 +1383,30 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
                }
        }
 
-       /* if not, then create one */
-       i = iNumServices;
-       tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
-       if (tsp == NULL) {
-               DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
-               return (-1);
+       /* Re use empty slots if any before allocating new one.*/
+       for (i=0; i < iNumServices; i++) {
+               if (ServicePtrs[i] == NULL) {
+                       break;
+               }
        }
-       ServicePtrs = tsp;
-       ServicePtrs[iNumServices] = talloc_zero(ServicePtrs, struct loadparm_service);
-       if (!ServicePtrs[iNumServices]) {
+       if (i == iNumServices) {
+               /* if not, then create one */
+               tsp = talloc_realloc(NULL, ServicePtrs,
+                                    struct loadparm_service *,
+                                    num_to_alloc);
+               if (tsp == NULL) {
+                       DEBUG(0, ("add_a_service: failed to enlarge "
+                                 "ServicePtrs!\n"));
+                       return (-1);
+               }
+               ServicePtrs = tsp;
+               iNumServices++;
+       }
+       ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
+       if (!ServicePtrs[i]) {
                DEBUG(0,("add_a_service: out of memory!\n"));
                return (-1);
        }
-       iNumServices++;
 
        ServicePtrs[i]->valid = true;
 
@@ -1559,6 +1572,7 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
        ServicePtrs[i]->guest_ok = guest_ok;
        ServicePtrs[i]->printable = false;
        ServicePtrs[i]->browseable = sDefault.browseable;
+       ServicePtrs[i]->autoloaded = true;
 
        DEBUG(3, ("adding IPC service\n"));