[SCM] Samba Shared Repository - branch v4-19-stable updated

Jule Anger janger at samba.org
Thu Oct 17 12:04:43 UTC 2024


The branch, v4-19-stable has been updated
       via  7eabe40bfe5 VERSION: Disable GIT_SNAPSHOT for the 4.19.9 release.
       via  4059e00109b WHATSNEW: Add release notes for Samba 4.19.9.
       via  8d4a277d258 BUG 15590 ldb: Release LDB 2.8.2
       via  5a15cbb15da ldb:kv_index: help static analysers to not worry (CID 1615192)
       via  9b33893987d ldb:kv_index: realloc away old dn list
       via  9a617692d29 ldb_kv_index: dn_list load sub transaction can re-use keys
       via  13cfe36b618 s4:lib/messaging: fix interaction between imessaging_reinit and irpc_destructor
       via  335ce71c636 smbd: remove just created sharemode entry in the error codepaths
       via  92d7e6c6339 smbd: consolidate DH reconnect failure code
       via  153f9027c96 s3:tests: let test_durable_handle_reconnect.sh run smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
       via  5f3f8835282 s4:torture/smb2: add smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
       via  b0fb5a1d39a vfs_error_inject: add 'error_inject:durable_reconnect = st_ex_nlink'
       via  3e6d740bf3e smbd: add option "smbd:debug events" for tevent handling duration threshold warnings
       via  38242b55d93 smbd: move trace_state variable behind tv variable
       via  2c8dfff7d9e smbd: add option "smbd lease break:debug hung procs"
       via  71568683ca7 smbd: log share_mode_watch_recv() errors as errors
       via  b5388c25b88 s3/lib: add option "serverid watch:debug script"
       via  b365e1068e4 s3/lib: add option "serverid watch:debug = yes" to print kernel stack of hanging process
       via  796d026919f s3/lib: add next helper variable in server_id_watch_*
       via  1602d847354 smb2_ioctl: fix truncated FSCTL_QUERY_ALLOCATED_RANGES responses
       via  3455944ce0a s4:torture/smb2: test FSCTL_QUERY_ALLOCATED_RANGES truncation
       via  a92076d88bf s3:smbd: fix NULL dereference in case of readlink failure
       via  2d944eb04ad s3:smb2_server: return NT_STATUS_NETWORK_SESSION_EXPIRED for compound requests
       via  3db88bd0527 s4:torture/smb2: let smb2.session.expire2* also check compound requests
       via  9d57d32bba0 VERSION: Bump version up to Samba 4.19.9...
      from  204b0f2d2f7 VERSION: Disable GIT_SNAPSHOT for the 4.19.8 release.

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


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 VERSION                                            |   2 +-
 WHATSNEW.txt                                       |  59 +++++++-
 lib/ldb/ABI/{ldb-2.8.0.sigs => ldb-2.8.2.sigs}     |   0
 ...pyldb-util-2.1.0.sigs => pyldb-util-2.8.2.sigs} |   0
 lib/ldb/ldb_key_value/ldb_kv_index.c               | 100 ++++++++------
 lib/ldb/wscript                                    |   2 +-
 selftest/skip                                      |   1 +
 source3/lib/server_id_watch.c                      | 128 +++++++++++++++++-
 source3/modules/vfs_error_inject.c                 |  76 +++++++++++
 .../script/tests/test_durable_handle_reconnect.sh  |  18 +++
 source3/smbd/durable.c                             | 150 ++++++++-------------
 source3/smbd/open.c                                | 119 ++++++++++++++--
 source3/smbd/smb2_ioctl.c                          |   4 +-
 source3/smbd/smb2_ioctl_filesys.c                  |  54 +++++---
 source3/smbd/smb2_process.c                        |  72 +++++++++-
 source3/smbd/smb2_server.c                         |  16 ++-
 source4/lib/messaging/messaging.c                  |   9 ++
 source4/libcli/smb2/ioctl.c                        |   3 +-
 source4/torture/smb2/durable_v2_open.c             | 118 ++++++++++++++++
 source4/torture/smb2/ioctl.c                       | 149 +++++++++++++++++++-
 source4/torture/smb2/session.c                     |  56 ++++++++
 source4/torture/smb2/smb2.c                        |   2 +
 22 files changed, 954 insertions(+), 184 deletions(-)
 copy lib/ldb/ABI/{ldb-2.8.0.sigs => ldb-2.8.2.sigs} (100%)
 copy lib/ldb/ABI/{pyldb-util-2.1.0.sigs => pyldb-util-2.8.2.sigs} (100%)


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 89a60174790..5a12a805f5b 100644
--- a/VERSION
+++ b/VERSION
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the Samba Team 1992-2023"
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=19
-SAMBA_VERSION_RELEASE=8
+SAMBA_VERSION_RELEASE=9
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 43b8cafa119..7747fe33732 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,59 @@
+                   ==============================
+                   Release Notes for Samba 4.19.9
+                          October 17, 2024
+                   ==============================
+
+
+This is the latest stable release of the Samba 4.19 release series.
+
+
+Changes since 4.19.8
+--------------------
+
+o  Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
+   * BUG 15590: libldb: performance issue with indexes (ldb 2.8.2 is already
+     released).
+
+o  Ralph Boehme <slow at samba.org>
+   * BUG 15624: DH reconnect error handling can lead to stale sharemode entries.
+
+o  David Disseldorp <ddiss at samba.org>
+   * BUG 15699: Incorrect FSCTL_QUERY_ALLOCATED_RANGES response when truncated.
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 15280: irpc_destructor may crash during shutdown.
+   * BUG 15624: DH reconnect error handling can lead to stale sharemode entries.
+   * BUG 15696: Compound SMB2 requests don't return
+     NT_STATUS_NETWORK_SESSION_EXPIRED for all requests, confuses
+     MacOSX clients.
+
+o  Shachar Sharon <ssharon at redhat.com>
+   * BUG 15700: Crash when readlinkat fails.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
                    ==============================
                    Release Notes for Samba 4.19.8
                           August 15, 2024
@@ -97,8 +153,7 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
                    ==============================
                    Release Notes for Samba 4.19.7
                            June 10, 2024
diff --git a/lib/ldb/ABI/ldb-2.8.0.sigs b/lib/ldb/ABI/ldb-2.8.2.sigs
similarity index 100%
copy from lib/ldb/ABI/ldb-2.8.0.sigs
copy to lib/ldb/ABI/ldb-2.8.2.sigs
diff --git a/lib/ldb/ABI/pyldb-util-2.1.0.sigs b/lib/ldb/ABI/pyldb-util-2.8.2.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-2.1.0.sigs
copy to lib/ldb/ABI/pyldb-util-2.8.2.sigs
diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c
index bcbd903f6fb..902fb9b69f2 100644
--- a/lib/ldb/ldb_key_value/ldb_kv_index.c
+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c
@@ -446,34 +446,39 @@ static int ldb_kv_dn_list_load(struct ldb_module *module,
 	 * There is an active index sub transaction, and the record was
 	 * found in the primary index transaction cache.  A copy of the
 	 * record needs be taken to prevent the original entry being
-	 * altered, until the index sub transaction is committed.
+	 * altered, until the index sub transaction is committed, but we
+	 * don't copy the actual values, just the array of struct ldb_val
+	 * that points to the values (which are offsets into a GUID array).
+	 *
+	 * As a reminder, our primary cache is an in-memory tdb that
+	 * maps attributes to struct dn_list objects, which point to
+	 * the actual index, which is an array of struct ldb_val, the
+	 * contents of which are {.data = <binary GUID>, .length =
+	 * 16}. The array is sorted by GUID data, and these GUIDs are
+	 * used to look up index entries in the main database. There
+	 * are more layers of indirection than necessary, but what
+	 * makes the index useful is we can use a binary search to
+	 * find if the array contains a GUID.
+	 *
+	 * What we do in a sub-transaction is make a copy of the struct
+	 * dn_list and the array of struct ldb_val, but *not* of the
+	 * .data that they point to. This copy is put into a new
+	 * in-memory tdb which masks the primary cache for the duration
+	 * of the sub-transaction.
+	 *
+	 * In an add operation in a sub-transaction, the new ldb_val
+	 * is a child of the sub-transaction dn_list, which will
+	 * become the main dn_list if the transaction succeeds.
+	 *
+	 * These acrobatics do not affect read-only operations.
 	 */
-
-	{
-		struct ldb_val *dns = NULL;
-		size_t x = 0;
-
-		dns = talloc_array(
-			list,
-			struct ldb_val,
-			list2->count);
-		if (dns == NULL) {
-			return LDB_ERR_OPERATIONS_ERROR;
-		}
-		for (x = 0; x < list2->count; x++) {
-			dns[x].length = list2->dn[x].length;
-			dns[x].data = talloc_memdup(
-				dns,
-				list2->dn[x].data,
-				list2->dn[x].length);
-			if (dns[x].data == NULL) {
-				TALLOC_FREE(dns);
-				return LDB_ERR_OPERATIONS_ERROR;
-			}
-		}
-		list->dn = dns;
-		list->count = list2->count;
+	list->dn = talloc_memdup(list,
+				 list2->dn,
+				 talloc_get_size(list2->dn));
+	if (list->dn == NULL) {
+		return LDB_ERR_OPERATIONS_ERROR;
 	}
+	list->count = list2->count;
 	return LDB_SUCCESS;
 
 	/*
@@ -3852,9 +3857,7 @@ int ldb_kv_reindex(struct ldb_module *module)
  * Copy the contents of the nested transaction index cache record to the
  * transaction index cache.
  *
- * During this 'commit' of the subtransaction to the main transaction
- * (cache), care must be taken to free any existing index at the top
- * level because otherwise we would leak memory.
+ * This is a 'commit' of the subtransaction to the main transaction cache.
  */
 static int ldb_kv_sub_transaction_traverse(
 	struct tdb_context *tdb,
@@ -3883,8 +3886,7 @@ static int ldb_kv_sub_transaction_traverse(
 
 	/*
 	 * Do we already have an entry in the primary transaction cache
-	 * If so free it's dn_list and replace it with the dn_list from
-	 * the secondary cache
+	 * If so replace dn_list with the one from the subtransaction.
 	 *
 	 * The TDB and so the fetched rec contains NO DATA, just a
 	 * pointer to data held in memory.
@@ -3897,21 +3899,41 @@ static int ldb_kv_sub_transaction_traverse(
 			abort();
 		}
 		/*
-		 * We had this key at the top level.  However we made a copy
-		 * at the sub-transaction level so that we could possibly
-		 * roll back.  We have to free the top level index memory
-		 * otherwise we would leak
+		 * We had this key at the top level, and made a copy
+		 * of the dn list for this sub-transaction level that
+		 * borrowed the top level GUID data. We can't free the
+		 * original dn list just yet.
+		 *
+		 * In this diagram, ... is the C pointer structure
+		 * and --- is the talloc structure (::: is both).
+		 *
+		 *   index_in_top_level ::: dn orig ..............
+		 *	|			|		  :
+		 *	|			`--GUID array	  :
+		 *	|				   |----- val1 data
+		 * ldb_kv				   `----- val2 data
+		 *	|					  :
+		 *   index_in_subtransaction :: dn copy ..........:
+		 *				|		  :
+		 *				`------------ new val3 data
+		 *
+		 * So we don't free the index_in_top_level dn list yet,
+		 * because we are (probably) borrowing most of its
+		 * children. But we can save memory by discarding the
+		 * values and keeping it as an almost empty talloc
+		 * node.
 		 */
-		if (index_in_top_level->count > 0) {
-			TALLOC_FREE(index_in_top_level->dn);
-		}
+		talloc_realloc(index_in_top_level,
+			       index_in_top_level->dn, struct ldb_val, 1);
 		index_in_top_level->dn
 			= talloc_steal(index_in_top_level,
 				       index_in_subtransaction->dn);
 		index_in_top_level->count = index_in_subtransaction->count;
 		return 0;
 	}
-
+	/*
+	 * We found no top level index in the cache, so we put one in.
+	 */
 	index_in_top_level = talloc(ldb_kv->idxptr, struct dn_list);
 	if (index_in_top_level == NULL) {
 		ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index 604294eeba9..0e53d4f2952 100644
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -2,7 +2,7 @@
 
 APPNAME = 'ldb'
 # For Samba 4.19.x !
-VERSION = '2.8.1'
+VERSION = '2.8.2'
 
 import sys, os
 
diff --git a/selftest/skip b/selftest/skip
index e808367c00d..056c54ea287 100644
--- a/selftest/skip
+++ b/selftest/skip
@@ -149,3 +149,4 @@ bench # don't run benchmarks in our selftest
 ^samba.tests.reparsepoints.*
 ^samba.tests.smb2symlink.*
 ^samba3.blackbox.open-eintr.*
+smb2.durable-v2-regressions # Only used in blackbox tests
diff --git a/source3/lib/server_id_watch.c b/source3/lib/server_id_watch.c
index f0189e0e896..8ddf9c6b1c8 100644
--- a/source3/lib/server_id_watch.c
+++ b/source3/lib/server_id_watch.c
@@ -17,16 +17,18 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "replace.h"
-#include <tevent.h>
-#include <talloc.h>
+#include "includes.h"
 #include "serverid.h"
 #include "server_id_watch.h"
+#include "lib/util/server_id.h"
 #include "lib/util/tevent_unix.h"
 
 struct server_id_watch_state {
 	struct tevent_context *ev;
 	struct server_id pid;
+	struct timeval start;
+	struct timeval warn;
+	bool debug;
 };
 
 static void server_id_watch_waited(struct tevent_req *subreq);
@@ -37,6 +39,7 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
 {
 	struct tevent_req *req, *subreq;
 	struct server_id_watch_state *state;
+	struct timeval next;
 
 	req = tevent_req_create(mem_ctx, &state, struct server_id_watch_state);
 	if (req == NULL) {
@@ -44,14 +47,21 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
 	}
 	state->ev = ev;
 	state->pid = pid;
+	state->start = tevent_timeval_current();
+	state->warn = tevent_timeval_add(&state->start, 10, 0);
+
+	state->debug = lp_parm_bool(GLOBAL_SECTION_SNUM,
+				    "serverid watch",
+				    "debug",
+				    CHECK_DEBUGLVL(DBGLVL_DEBUG));
 
 	if (!serverid_exists(&state->pid)) {
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = tevent_wakeup_send(
-		state, ev, tevent_timeval_current_ofs(0, 500000));
+	next = tevent_timeval_add(&state->start, 0, 500000);
+	subreq = tevent_wakeup_send(state, ev, next);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -66,6 +76,8 @@ static void server_id_watch_waited(struct tevent_req *subreq)
 		subreq, struct tevent_req);
 	struct server_id_watch_state *state = tevent_req_data(
 		req, struct server_id_watch_state);
+	struct timeval now;
+	struct timeval next;
 	bool ok;
 
 	ok = tevent_wakeup_recv(subreq);
@@ -80,8 +92,110 @@ static void server_id_watch_waited(struct tevent_req *subreq)
 		return;
 	}
 
-	subreq = tevent_wakeup_send(
-		state, state->ev, tevent_timeval_current_ofs(0, 500000));
+	now = tevent_timeval_current();
+
+	if (!state->debug) {
+		goto next;
+	}
+
+	if (timeval_compare(&state->warn, &now) == -1) {
+		double duration = timeval_elapsed2(&state->start, &now);
+		const char *cmd = NULL;
+		char proc_path[64] = { 0, };
+		char *kstack = NULL;
+		struct server_id_buf buf;
+		const char *pid = server_id_str_buf(state->pid, &buf);
+		int ret;
+
+		state->warn = tevent_timeval_add(&now, 10, 0);
+
+		cmd = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+					   "serverid watch",
+					   "debug script",
+					   NULL);
+		if (cmd != NULL) {
+			char *cmdstr = NULL;
+			char *output = NULL;
+			int fd;
+
+			/*
+			 * Note in a cluster setup pid will be
+			 * a NOTE:PID like '1:3978365'
+			 *
+			 * Without clustering it is just '3978365'
+			 */
+			cmdstr = talloc_asprintf(state, "%s %s", cmd, pid);
+			if (cmdstr == NULL) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"talloc_asprintf failed\n",
+					pid, duration);
+				goto next;
+			}
+
+			become_root();
+			ret = smbrun(cmdstr, &fd, NULL);
+			unbecome_root();
+			if (ret != 0) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"smbrun('%s') failed\n",
+					pid, duration, cmdstr);
+				TALLOC_FREE(cmdstr);
+				goto next;
+			}
+
+			output = fd_load(fd, NULL, 0, state);
+			close(fd);
+			if (output == NULL) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"fd_load() of smbrun('%s') failed\n",
+					pid, duration, cmdstr);
+				TALLOC_FREE(cmdstr);
+				goto next;
+			}
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"%s returned:\n%s",
+				pid, duration, cmdstr, output);
+			TALLOC_FREE(cmdstr);
+			TALLOC_FREE(output);
+			goto next;
+		}
+
+		if (!procid_is_local(&state->pid) || !sys_have_proc_fds()) {
+			DBG_ERR("Process %s hanging for %f seconds?\n",
+				pid, duration);
+			goto next;
+		}
+
+		ret = snprintf(proc_path,
+			       ARRAY_SIZE(proc_path),
+			       "/proc/%" PRIu64 "/stack",
+			       state->pid.pid);
+		if (ret < 0) {
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"snprintf failed\n",
+				pid, duration);
+			goto next;
+		}
+
+		become_root();
+		kstack = file_load(proc_path, NULL, 0, state);
+		unbecome_root();
+		if (kstack == NULL) {
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"file_load [%s] failed\n",
+				pid, duration, proc_path);
+			goto next;
+		}
+
+		DBG_ERR("Process %s hanging for %f seconds?\n"
+			"%s:\n%s",
+			pid, duration, proc_path, kstack);
+		TALLOC_FREE(kstack);
+	}
+
+next:
+	next = tevent_timeval_add(&now, 0, 500000);
+	subreq = tevent_wakeup_send(state, state->ev, next);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
index 529504fd8d5..dcf0de0a2d9 100644
--- a/source3/modules/vfs_error_inject.c
+++ b/source3/modules/vfs_error_inject.c
@@ -19,6 +19,7 @@
 
 #include "includes.h"
 #include "smbd/smbd.h"
+#include "librpc/gen_ndr/ndr_open_files.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -204,11 +205,86 @@ static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
 	return -1;
 }
 
+static NTSTATUS vfs_error_inject_durable_reconnect(struct vfs_handle_struct *handle,
+						   struct smb_request *smb1req,
+						   struct smbXsrv_open *op,
+						   const DATA_BLOB old_cookie,
+						   TALLOC_CTX *mem_ctx,
+						   struct files_struct **fsp,
+						   DATA_BLOB *new_cookie)
+{
+	const char *vfs_func = "durable_reconnect";
+	const char *err_str = NULL;
+	NTSTATUS status;
+	enum ndr_err_code ndr_err;
+	struct vfs_default_durable_cookie cookie;
+	DATA_BLOB modified_cookie = data_blob_null;
+
+	err_str = lp_parm_const_string(SNUM(handle->conn),
+				       "error_inject",
+				       vfs_func,
+				       NULL);
+	if (err_str == NULL) {
+		return SMB_VFS_NEXT_DURABLE_RECONNECT(handle,
+						      smb1req,
+						      op,
+						      old_cookie,
+						      mem_ctx,
+						      fsp,
+						      new_cookie);
+	}
+
+	ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
+			(ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (strequal(err_str, "st_ex_nlink")) {
+		cookie.stat_info.st_ex_nlink += 1;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list