Fix bug 10216

Volker Lendecke Volker.Lendecke at SerNet.DE
Mon Oct 21 08:49:52 MDT 2013


Hi!

Attached find a bugfix for 10216. Only in master.

Please review&push!

Thanks,

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 7c06a25bae4db1332fb95ce2a6f4637977bf3635 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 18 Oct 2013 15:12:35 +0000
Subject: [PATCH 1/2] smbd: Fix bug 10216

While refactoring find_oplock_types to validate_oplock_types I forgot
that stat opens will end up in locking.tdb. So even with a batch oplock
around we can have more than one entry. This means the consistency check
in validate_oplock_types was wrong and too strict.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/smbd/open.c |   32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index fa52fcc..c3e1a76 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1211,6 +1211,7 @@ static bool validate_oplock_types(files_struct *fsp,
 	bool ex_or_batch = false;
 	bool level2 = false;
 	bool no_oplock = false;
+	uint32_t num_non_stat_opens = 0;
 	uint32_t i;
 
 	/* Ignore stat or internal opens, as is done in
@@ -1235,6 +1236,8 @@ static bool validate_oplock_types(files_struct *fsp,
 			continue;
 		}
 
+		num_non_stat_opens += 1;
+
 		if (BATCH_OPLOCK_TYPE(e->op_type)) {
 			/* batch - can only be one. */
 			if (share_mode_stale_pid(d, i)) {
@@ -1294,7 +1297,7 @@ static bool validate_oplock_types(files_struct *fsp,
 
 	remove_stale_share_mode_entries(d);
 
-	if ((batch || ex_or_batch) && (d->num_share_modes != 1)) {
+	if ((batch || ex_or_batch) && (num_non_stat_opens != 1)) {
 		DEBUG(1, ("got batch (%d) or ex (%d) non-exclusively (%d)\n",
 			  (int)batch, (int)ex_or_batch,
 			  (int)d->num_share_modes));
@@ -1312,17 +1315,38 @@ static bool delay_for_oplock(files_struct *fsp,
 {
 	struct share_mode_data *d = lck->data;
 	struct share_mode_entry *entry;
+	uint32_t num_non_stat_opens = 0;
+	uint32_t i;
 
 	if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
 		return false;
 	}
-	if (lck->data->num_share_modes != 1) {
+	for (i=0; i<d->num_share_modes; i++) {
+		struct share_mode_entry *e = &d->share_modes[i];
+		if (e->op_type == NO_OPLOCK && is_stat_open(e->access_mask)) {
+			continue;
+		}
+		num_non_stat_opens += 1;
+
+		/*
+		 * We found the a non-stat open, which in the exclusive/batch
+		 * case will be inspected further down.
+		 */
+		entry = e;
+	}
+	if (num_non_stat_opens == 0) {
+		/*
+		 * Nothing to wait for around
+		 */
+		return false;
+	}
+	if (num_non_stat_opens != 1) {
 		/*
-		 * More than one. There can't be any exclusive or batch left.
+		 * More than one open around. There can't be any exclusive or
+		 * batch left, this is all level2.
 		 */
 		return false;
 	}
-	entry = &d->share_modes[0];
 
 	if (server_id_is_disconnected(&entry->pid)) {
 		/*
-- 
1.7.9.5


From 49c2c19bf2f4e4e9e0b3f18289b6f82a8ea47493 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 18 Oct 2013 13:11:38 +0000
Subject: [PATCH 2/2] torture: Add reproducer for bug 10216

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source4/torture/raw/oplock.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 34e270d..c0738e9 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -556,6 +556,18 @@ static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbc
 	CHECK_VAL(break_info.count, 0);
 	CHECK_VAL(break_info.failures, 0);
 
+	/*
+	 * Open another non-stat open. This reproduces bug 10216. Make sure it
+	 * won't happen again...
+	 */
+	io.ntcreatex.in.flags = 0;
+	io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
+	status = smb_raw_open(cli2->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+	torture_wait_for_oplock_break(tctx);
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+
 	smbcli_close(cli1->tree, fnum);
 	smbcli_close(cli2->tree, fnum2);
 
-- 
1.7.9.5



More information about the samba-technical mailing list