summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHemanth Thummala <hemanth.thummala@nutanix.com>2016-02-16 14:44:38 -0800
committerKarolin Seeger <kseeger@samba.org>2016-02-22 19:33:58 +0100
commita2aea37161f55475e5fb25cf92a2b050389bb412 (patch)
tree5ed60be0ffdc4648959931bace2a4e97776e5c5c
parent956289e6b55e2917ac539de1eb32c33d83d28c7c (diff)
downloadsamba-a2aea37161f55475e5fb25cf92a2b050389bb412.tar.gz
Real memeory leak(buildup) issue in loadparm.
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 (cherry picked from commit 03081c2c1484504bdcc0e111b2df95e073c1c166) Autobuild-User(v4-4-test): Karolin Seeger <kseeger@samba.org> Autobuild-Date(v4-4-test): Mon Feb 22 19:33:58 CET 2016 on sn-devel-144
-rw-r--r--source3/param/loadparm.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index fb92230ffba..605555e4c87 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -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"));