[SCM] Samba Shared Repository - branch v4-14-test updated

Karolin Seeger kseeger at samba.org
Wed Mar 31 11:11:01 UTC 2021


The branch, v4-14-test has been updated
       via  051585ef361 smbd: free open_rec state in remove_deferred_open_message_smb2_internal()
       via  ebec84c886e smbd: cancel pending poll open timer in poll_open_done()
       via  da71738e987 smbd: reset dangling watch_req pointer in poll_open_done
       via  288c7472083 s3:modules:vfs_virusfilter: Recent New_VFS changes break vfs_virusfilter_openat.
       via  a164468a406 samba-gpupdate: Check sysvol download paths in case-insensitive way
       via  702e0c55989 samba-gpupdate: Test that sysvol paths download in case-insensitive way
       via  231342faf2f idmap_nss: Do not return SID from unixids_to_sids on type mismatch
       via  7628a27a96b idmap_rfc2307: Do not return SID from unixids_to_sids on type mismatch
       via  e7b1ee061ea winbind: Only use unixid2sid mapping when module reports ID_MAPPED
       via  6b8226b7355 smbd: Ensure errno is preserved across fsp destructor
       via  a0862d6d6de third_party: Update socket_wrapper to version 1.3.3
       via  ed3c83a7f8c third_party: Update socket_wrapper to version 1.3.2
      from  6e981465fce VERSION: Bump version up to 4.14.2...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-14-test


- Log -----------------------------------------------------------------
commit 051585ef3616fc845ebbcbcf18c46f9d0cab2b00
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Mar 16 18:18:46 2021 +0100

    smbd: free open_rec state in remove_deferred_open_message_smb2_internal()
    
    The lifetime of open_rec (struct deferred_open_record) ojects is the time
    processing the SMB open request every time the request is scheduled, ie once we
    reschedule we must wipe the slate clean. In case the request gets deferred
    again, a new open_rec will be created by the schedule functions.
    
    This ensures any timer-event tied to the open_rec gets cancelled and doesn't
    fire unexpectedly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672
    CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843
    RN: smbd panic when two clients open same file
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Mar 18 18:04:09 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 591c9196962b695b01c0d86918b8f8a263e9665c)
    
    Autobuild-User(v4-14-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-14-test): Wed Mar 31 11:10:29 UTC 2021 on sn-devel-184

commit ebec84c886e7d7807609a3492e02fd1347898aba
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Mar 17 16:24:28 2021 +0100

    smbd: cancel pending poll open timer in poll_open_done()
    
    The retry of the open is scheduled below, avoid rescheduling it a second time in
    the open retry timeout function.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672
    CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 171a58ff3e8ee07cf5d7af08eabcb4a7379e7ce5)

commit da71738e987310f19d63d2b575c354156dadbf8f
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Mar 17 16:22:37 2021 +0100

    smbd: reset dangling watch_req pointer in poll_open_done
    
    We just freed subreq and a pointer to subreq is stored in open_rec->watch_req,
    so we must invalidate the pointer.
    
    Otherwise if the poll open timer fires it will do a
    
      TALLOC_FREE(open_rec->watch_req);
    
    on the dangling pointer which may crash or do something worse like freeing some
    other random talloc memory.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14672
    CI: https://gitlab.com/samba-team/samba/-/merge_requests/1843
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 065ed088b3d5710c288e46a5bf1e063f9a29c8cc)

commit 288c747208318a067836ed74afa138ae7b261464
Author: Trever L. Adams <trever.adams at gmail.com>
Date:   Sat Mar 13 12:47:21 2021 -0700

    s3:modules:vfs_virusfilter: Recent New_VFS changes break vfs_virusfilter_openat.
    
    The_New_VFS introduces several changes that broke vfs_virusfilter_openat. The assert to make sure certain checks would work broke.
    
    This patch fixes those breaks and converts to the SMB_VFS_FSTAT_NEXT instead of SMB_VFS_STAT_NEXT.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14671
    RN: vfs_virusfilter_openat support New_VFS FSTAT, avoid SMB_ASSERT(fsp_get_pathref_fd(dirfsp) == AT_FDCWD); problem.
    
    Signed-off-by: Trever L. Adams" <trever.adams at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Noel Power <npower at samba.org>
    
    Autobuild-User(master): Noel Power <npower at samba.org>
    Autobuild-Date(master): Mon Mar 22 19:44:30 UTC 2021 on sn-devel-184
    
    (cherry picked from commit d6a16ad00e426a6f815215af71c071dd8e85a50a)

commit a164468a406fb19f017752bb4de377c6bd0eaaa1
Author: David Mulder <dmulder at suse.com>
Date:   Tue Mar 9 11:13:40 2021 -0700

    samba-gpupdate: Check sysvol download paths in case-insensitive way
    
    https://bugzilla.samba.org/show_bug.cgi?id=14665
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Björn Baumbach <bb at sernet.de>
    (cherry picked from commit 2d6bed495e14349e19ba680bd72c3f110f1c397b)

commit 702e0c55989b9e2975eb761c6776d3b866ee512f
Author: David Mulder <dmulder at suse.com>
Date:   Tue Mar 9 12:30:14 2021 -0700

    samba-gpupdate: Test that sysvol paths download in case-insensitive way
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14665
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Björn Baumbach <bb at sernet.de>
    (cherry picked from commit 554f2134a9f9638ebd8ac2500e5b6c94b74c27d5)

commit 231342faf2f5f6ab2287967f317cb1a862083a7f
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Mar 5 16:07:54 2021 -0700

    idmap_nss: Do not return SID from unixids_to_sids on type mismatch
    
    The call to winbind_lookup_name already wrote the result in the id_map
    array. The later check for the type detected a mismatch, but that did
    not remove the SID from the result struct.
    
    Change this by first assigning the SID to a temporary variable and only
    write it to the id_map array after the type checks.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Thu Mar 11 08:38:41 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 0e789ba1802ca22e5a01abd6e93ef66cd45566a7)

commit 7628a27a96bf817dd1707b123b792e7e1689edd2
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Mar 5 16:01:13 2021 -0700

    idmap_rfc2307: Do not return SID from unixids_to_sids on type mismatch
    
    The call to winbind_lookup_name already wrote the result in the id_map
    array. The later check for the type detected a mismatch, but that did
    not remove the SID from the result struct.
    
    Change this by first assigning the SID to a temporary variable and only
    write it to the id_map array after the type checks.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    (cherry picked from commit 79dd4b133c37451c98fe7f7c45da881e89e91ffc)

commit e7b1ee061eaa335d70dc354dfb3700f8344274c9
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Mar 5 15:48:29 2021 -0700

    winbind: Only use unixid2sid mapping when module reports ID_MAPPED
    
    Only consider a mapping to be valid when the idmap module reports
    ID_MAPPED. Otherwise return the null SID.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14663
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    (cherry picked from commit db2afa57e4aa926b478db1be4d693edbdf4d2a23)

commit 6b8226b7355ca7c290d859e5cdbac7d72b24a3c1
Author: Sachin Prabhu <sprabhu at redhat.com>
Date:   Wed Mar 10 12:22:07 2021 +0000

    smbd: Ensure errno is preserved across fsp destructor
    
    The errno can be overwritten by the calls made by the fsp destructor.
    This can cause problems if the original errno was required by subsequent
    calls.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14662
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: Sachin Prabhu <sprabhu at redhat.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Mar 10 22:55:17 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 65510204d4123b1825ea57607e84ba50f8ce3baf)

commit a0862d6d6dee5f21bebf8987e3e7a21a42198b3b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Feb 17 12:57:01 2021 +0100

    third_party: Update socket_wrapper to version 1.3.3
    
    This fixes a deadlock abort() when SOCKET_WRAPPER_KEEP_PCAP=1
    is used.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14640
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Wed Mar 17 23:53:04 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 10c198827d977e07b411897556578d3aedce2184)

commit ed3c83a7f8c955b524e3203263eb5e17ed940fee
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 9 08:56:42 2021 +0100

    third_party: Update socket_wrapper to version 1.3.2
    
    This brings support for fd-passing of INET sockets.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11899
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit ab943babc3eb454186558f6e863996dfcf7a20ea)

-----------------------------------------------------------------------

Summary of changes:
 buildtools/wafsamba/samba_third_party.py    |    2 +-
 python/samba/gpclass.py                     |    5 +-
 python/samba/tests/gpo.py                   |   10 +
 source3/modules/vfs_virusfilter.c           |    8 +-
 source3/smbd/files.c                        |    3 +
 source3/smbd/open.c                         |    3 +
 source3/smbd/smb2_create.c                  |    1 +
 source3/winbindd/idmap_nss.c                |    6 +-
 source3/winbindd/idmap_rfc2307.c            |    4 +-
 source3/winbindd/winbindd_dual_srv.c        |    8 +-
 third_party/socket_wrapper/socket_wrapper.c | 1710 ++++++++++++++++++++++-----
 third_party/socket_wrapper/socket_wrapper.h |   89 ++
 third_party/socket_wrapper/wscript          |    8 +-
 13 files changed, 1554 insertions(+), 303 deletions(-)
 create mode 100644 third_party/socket_wrapper/socket_wrapper.h


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
index bc2b21f2a55..1c027cb6870 100644
--- a/buildtools/wafsamba/samba_third_party.py
+++ b/buildtools/wafsamba/samba_third_party.py
@@ -24,7 +24,7 @@ Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
 
 @conf
 def CHECK_SOCKET_WRAPPER(conf):
-    return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.5')
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.3')
 Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER
 
 @conf
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 1b29711f245..838ef50ac3c 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -393,8 +393,9 @@ def cache_gpo_dir(conn, cache, sub_dir):
 
 def check_safe_path(path):
     dirs = re.split('/|\\\\', path)
-    if 'sysvol' in path:
-        dirs = dirs[dirs.index('sysvol') + 1:]
+    if 'sysvol' in path.lower():
+        ldirs = re.split('/|\\\\', path.lower())
+        dirs = dirs[ldirs.index('sysvol') + 1:]
     if '..' not in dirs:
         return os.path.join(*dirs)
     raise OSError(path)
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index a0dce8d96d7..0afc2091b3e 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -181,6 +181,16 @@ class GPOTests(tests.TestCase):
         self.assertEqual(result, after, 'check_safe_path() didn\'t'
                           ' correctly convert \\ to /')
 
+    def test_check_safe_path_typesafe_name(self):
+        path = '\\\\toady.suse.de\\SysVol\\toady.suse.de\\Policies\\' \
+               '{31B2F340-016D-11D2-945F-00C04FB984F9}\\GPT.INI'
+        expected_path = 'toady.suse.de/Policies/' \
+                        '{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI'
+
+        result = check_safe_path(path)
+        self.assertEqual(result, expected_path,
+            'check_safe_path unable to detect variable case sysvol components')
+
     def test_gpt_ext_register(self):
         this_path = os.path.dirname(os.path.realpath(__file__))
         samba_path = os.path.realpath(os.path.join(this_path, '../../../'))
diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
index c9f5e2bf908..524e7dfbad9 100644
--- a/source3/modules/vfs_virusfilter.c
+++ b/source3/modules/vfs_virusfilter.c
@@ -1238,11 +1238,7 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
 	bool ok1;
 	char *sret = NULL;
 	struct smb_filename *smb_fname = NULL;
-
-	/*
-	 * For now assert this, so SMB_VFS_NEXT_STAT() below works.
-	 */
-	SMB_ASSERT(fsp_get_pathref_fd(dirfsp) == AT_FDCWD);
+	SMB_STRUCT_STAT sbuf = smb_fname_in->st;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, config,
 				struct virusfilter_config, return -1);
@@ -1284,7 +1280,7 @@ static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
 		goto virusfilter_vfs_open_next;
 	}
 
-	ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+	ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf);
 	if (ret != 0) {
 
 		/*
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index f60d5979f53..d9fd2b8ea86 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -358,10 +358,12 @@ static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
 {
 	struct files_struct *fsp = smb_fname->fsp;
 	NTSTATUS status;
+	int saved_errno = errno;
 
 	destroy_fsp_smb_fname_link(&smb_fname->fsp_link);
 
 	if (fsp == NULL) {
+		errno = saved_errno;
 		return 0;
 	}
 
@@ -380,6 +382,7 @@ static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
 	file_free(NULL, fsp);
 	smb_fname->fsp = NULL;
 
+	errno = saved_errno;
 	return 0;
 }
 
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b82eb2f02b9..87c14bb4367 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3040,6 +3040,9 @@ static void poll_open_done(struct tevent_req *subreq)
 
 	status = share_mode_watch_recv(subreq, NULL, NULL);
 	TALLOC_FREE(subreq);
+	open_rec->watch_req = NULL;
+	TALLOC_FREE(open_rec->te);
+
 	DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
 		  nt_errstr(status));
 
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 2dd3745dd32..8ff57c94aa0 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -1714,6 +1714,7 @@ static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request
 	state->open_was_deferred = false;
 	/* Ensure we don't have any outstanding immediate event. */
 	TALLOC_FREE(state->im);
+	TALLOC_FREE(state->open_rec);
 }
 
 void remove_deferred_open_message_smb2(
diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
index 9e1efefeb24..da50e2b4aa7 100644
--- a/source3/winbindd/idmap_nss.c
+++ b/source3/winbindd/idmap_nss.c
@@ -25,6 +25,7 @@
 #include "nsswitch/winbind_client.h"
 #include "idmap.h"
 #include "lib/winbind_util.h"
+#include "libcli/security/dom_sid.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -55,6 +56,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
 		struct passwd *pw;
 		struct group *gr;
 		const char *name;
+		struct dom_sid sid;
 		enum lsa_SidType type;
 		bool ret;
 
@@ -86,7 +88,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
 		   the following call will not recurse so this is safe */
 		(void)winbind_on();
 		/* Lookup name from PDC using lsa_lookup_names() */
-		ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
+		ret = winbind_lookup_name(dom->name, name, &sid, &type);
 		(void)winbind_off();
 
 		if (!ret) {
@@ -99,6 +101,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
 		switch (type) {
 		case SID_NAME_USER:
 			if (ids[i]->xid.type == ID_TYPE_UID) {
+				sid_copy(ids[i]->sid, &sid);
 				ids[i]->status = ID_MAPPED;
 			}
 			break;
@@ -107,6 +110,7 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
 		case SID_NAME_ALIAS:
 		case SID_NAME_WKN_GRP:
 			if (ids[i]->xid.type == ID_TYPE_GID) {
+				sid_copy(ids[i]->sid, &sid);
 				ids[i]->status = ID_MAPPED;
 			}
 			break;
diff --git a/source3/winbindd/idmap_rfc2307.c b/source3/winbindd/idmap_rfc2307.c
index 05259bf8344..4870ca30485 100644
--- a/source3/winbindd/idmap_rfc2307.c
+++ b/source3/winbindd/idmap_rfc2307.c
@@ -229,6 +229,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
 
 	for (i = 0; i < count; i++) {
 		char *name;
+		struct dom_sid sid;
 		enum lsa_SidType lsa_type;
 		struct id_map *map;
 		uint32_t id;
@@ -277,7 +278,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
 		   the following call will not recurse so this is safe */
 		(void)winbind_on();
 		/* Lookup name from PDC using lsa_lookup_names() */
-		b = winbind_lookup_name(dom_name, name, map->sid, &lsa_type);
+		b = winbind_lookup_name(dom_name, name, &sid, &lsa_type);
 		(void)winbind_off();
 
 		if (!b) {
@@ -301,6 +302,7 @@ static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
 		}
 
 		map->status = ID_MAPPED;
+		sid_copy(map->sid, &sid);
 	}
 }
 
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index ffd7bb957b2..32d11e1fa57 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -283,8 +283,12 @@ NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
 	}
 
 	for (i=0; i<r->in.num_ids; i++) {
-		r->out.xids[i] = maps[i]->xid;
-		sid_copy(&r->out.sids[i], maps[i]->sid);
+		if (maps[i]->status == ID_MAPPED) {
+			r->out.xids[i] = maps[i]->xid;
+			sid_copy(&r->out.sids[i], maps[i]->sid);
+		} else {
+			r->out.sids[i] = (struct dom_sid) { 0 };
+		}
 	}
 
 	TALLOC_FREE(maps);
diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c
index ffdd31a51bf..44cfad8c6cf 100644
--- a/third_party/socket_wrapper/socket_wrapper.c
+++ b/third_party/socket_wrapper/socket_wrapper.c
@@ -2,8 +2,8 @@
  * BSD 3-Clause License
  *
  * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer at samba.org>
- * Copyright (c) 2006-2018, Stefan Metzmacher <metze at samba.org>
- * Copyright (c) 2013-2018, Andreas Schneider <asn at samba.org>
+ * Copyright (c) 2006-2021, Stefan Metzmacher <metze at samba.org>
+ * Copyright (c) 2013-2021, Andreas Schneider <asn at samba.org>
  * Copyright (c) 2014-2017, Michael Adam <obnox at samba.org>
  * Copyright (c) 2016-2018, Anoop C S <anoopcs at redhat.com>
  * All rights reserved.
@@ -86,6 +86,8 @@
 #endif
 #include <pthread.h>
 
+#include "socket_wrapper.h"
+
 enum swrap_dbglvl_e {
 	SWRAP_LOG_ERROR = 0,
 	SWRAP_LOG_WARN,
@@ -178,24 +180,67 @@ enum swrap_dbglvl_e {
 # endif
 #endif
 
+#define socket_wrapper_init_mutex(m) \
+	_socket_wrapper_init_mutex(m, #m)
+
 /* Add new global locks here please */
-# define SWRAP_LOCK_ALL \
-	swrap_mutex_lock(&libc_symbol_binding_mutex); \
+# define SWRAP_REINIT_ALL do { \
+	int ret; \
+	ret = socket_wrapper_init_mutex(&sockets_mutex); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&socket_reset_mutex); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&first_free_mutex); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&sockets_si_global); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&autobind_start_mutex); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \
+	if (ret != 0) exit(-1); \
+	ret = socket_wrapper_init_mutex(&mtu_update_mutex); \
+	if (ret != 0) exit(-1); \
+} while(0)
+
+# define SWRAP_LOCK_ALL do { \
+	swrap_mutex_lock(&sockets_mutex); \
+	swrap_mutex_lock(&socket_reset_mutex); \
+	swrap_mutex_lock(&first_free_mutex); \
+	swrap_mutex_lock(&sockets_si_global); \
+	swrap_mutex_lock(&autobind_start_mutex); \
+	swrap_mutex_lock(&pcap_dump_mutex); \
+	swrap_mutex_lock(&mtu_update_mutex); \
+} while(0)
 
-# define SWRAP_UNLOCK_ALL \
-	swrap_mutex_unlock(&libc_symbol_binding_mutex); \
+# define SWRAP_UNLOCK_ALL do { \
+	swrap_mutex_unlock(&mtu_update_mutex); \
+	swrap_mutex_unlock(&pcap_dump_mutex); \
+	swrap_mutex_unlock(&autobind_start_mutex); \
+	swrap_mutex_unlock(&sockets_si_global); \
+	swrap_mutex_unlock(&first_free_mutex); \
+	swrap_mutex_unlock(&socket_reset_mutex); \
+	swrap_mutex_unlock(&sockets_mutex); \
+} while(0)
 
 #define SOCKET_INFO_CONTAINER(si) \
 	(struct socket_info_container *)(si)
 
 #define SWRAP_LOCK_SI(si) do { \
 	struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
-	swrap_mutex_lock(&sic->meta.mutex); \
+	if (sic != NULL) { \
+		swrap_mutex_lock(&sockets_si_global); \
+	} else { \
+		abort(); \
+	} \
 } while(0)
 
 #define SWRAP_UNLOCK_SI(si) do { \
 	struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
-	swrap_mutex_unlock(&sic->meta.mutex); \
+	if (sic != NULL) { \
+		swrap_mutex_unlock(&sockets_si_global); \
+	} else { \
+		abort(); \
+	} \
 } while(0)
 
 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
@@ -253,10 +298,15 @@ struct swrap_address {
 	} sa;
 };
 
-int first_free;
+static int first_free;
 
 struct socket_info
 {
+	/*
+	 * Remember to update swrap_unix_scm_right_magic
+	 * on any change.
+	 */
+
 	int family;
 	int type;
 	int protocol;
@@ -268,6 +318,7 @@ struct socket_info
 	int pktinfo;
 	int tcp_nodelay;
 	int listening;
+	int fd_passed;
 
 	/* The unix path so we can unlink it on close() */
 	struct sockaddr_un un_addr;
@@ -286,7 +337,13 @@ struct socket_info_meta
 {
 	unsigned int refcount;
 	int next_free;
-	pthread_mutex_t mutex;
+	/*
+	 * As long as we don't use shared memory
+	 * for the sockets array, we use
+	 * sockets_si_global as a single mutex.
+	 *
+	 * pthread_mutex_t mutex;
+	 */
 };
 
 struct socket_info_container
@@ -309,32 +366,42 @@ static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
 /* Hash table to map fds to corresponding socket_info index */
 static int *socket_fds_idx;
 
-/* Mutex to synchronize access to global libc.symbols */
-static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
-
 /* Mutex for syncronizing port selection during swrap_auto_bind() */
-static pthread_mutex_t autobind_start_mutex;
+static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Mutex to guard the initialization of array of socket_info structures */
-static pthread_mutex_t sockets_mutex;
+static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-/* Mutex to guard the socket reset in swrap_close() and swrap_remove_stale() */
-static pthread_mutex_t socket_reset_mutex;
+/* Mutex to guard the socket reset in swrap_remove_wrapper() */
+static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Mutex to synchronize access to first free index in socket_info array */
-static pthread_mutex_t first_free_mutex;
+static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * Mutex to synchronize access to to socket_info structures
+ * We use a single global mutex in order to avoid leaking
+ * ~ 38M copy on write memory per fork.
+ * max_sockets=65535 * sizeof(struct socket_info_container)=592 = 38796720
+ */
+static pthread_mutex_t sockets_si_global = PTHREAD_MUTEX_INITIALIZER;
 
 /* Mutex to synchronize access to packet capture dump file */
-static pthread_mutex_t pcap_dump_mutex;
+static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Mutex for synchronizing mtu value fetch*/
-static pthread_mutex_t mtu_update_mutex;
+static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Function prototypes */
 
-bool socket_wrapper_enabled(void);
-
+#if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
+/* xlC and other oldschool compilers support (only) this */
+#pragma init (swrap_constructor)
+#endif
 void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
+#if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
+#pragma fini (swrap_destructor)
+#endif
 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
 
 #ifndef HAVE_GETPROGNAME
@@ -425,6 +492,9 @@ typedef int (*__libc_bind)(int sockfd,
 			   const struct sockaddr *addr,
 			   socklen_t addrlen);
 typedef int (*__libc_close)(int fd);
+#ifdef HAVE___CLOSE_NOCANCEL
+typedef int (*__libc___close_nocancel)(int fd);
+#endif
 typedef int (*__libc_connect)(int sockfd,
 			      const struct sockaddr *addr,
 			      socklen_t addrlen);
@@ -505,6 +575,9 @@ struct swrap_libc_symbols {
 #endif
 	SWRAP_SYMBOL_ENTRY(bind);
 	SWRAP_SYMBOL_ENTRY(close);
+#ifdef HAVE___CLOSE_NOCANCEL
+	SWRAP_SYMBOL_ENTRY(__close_nocancel);
+#endif
 	SWRAP_SYMBOL_ENTRY(connect);
 	SWRAP_SYMBOL_ENTRY(dup);
 	SWRAP_SYMBOL_ENTRY(dup2);
@@ -565,7 +638,6 @@ static char *socket_wrapper_dir(void);
 
 enum swrap_lib {
     SWRAP_LIBC,
-    SWRAP_LIBNSL,
     SWRAP_LIBSOCKET,
 };
 
@@ -574,8 +646,6 @@ static const char *swrap_str_lib(enum swrap_lib lib)
 	switch (lib) {
 	case SWRAP_LIBC:
 		return "libc";
-	case SWRAP_LIBNSL:
-		return "libnsl";
 	case SWRAP_LIBSOCKET:
 		return "libsocket";
 	}
@@ -613,7 +683,6 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 #endif
 
 	switch (lib) {
-	case SWRAP_LIBNSL:
 	case SWRAP_LIBSOCKET:
 #ifdef HAVE_LIBSOCKET
 		handle = swrap.libc.socket_handle;
@@ -695,25 +764,29 @@ static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
 	return func;
 }
 
-static void swrap_mutex_lock(pthread_mutex_t *mutex)
+#define swrap_mutex_lock(m) _swrap_mutex_lock(m, #m, __func__, __LINE__)
+static void _swrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
 {
 	int ret;
 
 	ret = pthread_mutex_lock(mutex);
 	if (ret != 0) {
-		SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't lock pthread mutex - %s",
-			  strerror(ret));
+		SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s",
+			  getpid(), getppid(), caller, line, name, strerror(ret));
+		abort();
 	}
 }
 
-static void swrap_mutex_unlock(pthread_mutex_t *mutex)
+#define swrap_mutex_unlock(m) _swrap_mutex_unlock(m, #m, __func__, __LINE__)
+static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
 {
 	int ret;
 
 	ret = pthread_mutex_unlock(mutex);
 	if (ret != 0) {
-		SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't unlock pthread mutex - %s",
-			  strerror(ret));
+		SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s",
+			  getpid(), getppid(), caller, line, name, strerror(ret));
+		abort();
 	}
 }
 
@@ -723,35 +796,18 @@ static void swrap_mutex_unlock(pthread_mutex_t *mutex)
  * This is an optimization to avoid locking each time we check if the symbol is
  * bound.
  */
+#define _swrap_bind_symbol_generic(lib, sym_name) do { \
+	swrap.libc.symbols._libc_##sym_name.obj = \


-- 
Samba Shared Repository



More information about the samba-cvs mailing list