[PATCH] Fix bug #9794 - opening/editing or copying MS files causes a core dump with invalid lock order

Jeremy Allison jra at samba.org
Thu Apr 25 15:42:21 MDT 2013


Here is a modest fix to apply to master to fix
the bug in the subject line.

The real bug is that the function open_file_fchmod()
can be called inside of an open file request inside
of create_file_default(), but that requires a follow-up
patchset that will be 4.1.x (i.e. master-only).

Please review and push if you approve.

Jeremy.
-------------- next part --------------
From 52150de2b088f0bddb76e59caab31d674f02516c Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 Apr 2013 13:59:22 -0700
Subject: [PATCH 1/4] Add early return in file_set_dosmode() on a read only
 share.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/dosmode.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 19b7675..cd7a1fd 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -706,6 +706,11 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 	uint32_t old_mode;
 	struct timespec new_create_timespec;
 
+	if (!CAN_WRITE(conn)) {
+		errno = EROFS;
+		return -1;
+	}
+
 	/* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
 	dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE);
 
-- 
1.8.2.1


From 8230d700af114c5101b0c8b9b9bc32a441794769 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 Apr 2013 14:00:42 -0700
Subject: [PATCH 2/4] Remove indentation around code wrapped by unneeded
 CAN_WRITE.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/dosmode.c | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index cd7a1fd..1fb0088 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -705,6 +705,7 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 	int ret = -1, lret = -1;
 	uint32_t old_mode;
 	struct timespec new_create_timespec;
+	files_struct *fsp = NULL;
 
 	if (!CAN_WRITE(conn)) {
 		errno = EROFS;
@@ -855,29 +856,25 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 		bits on a file. Just like file_ntimes below.
 	*/
 
-	/* Check if we have write access. */
-	if (CAN_WRITE(conn)) {
-		/*
-		 * We need to open the file with write access whilst
-		 * still in our current user context. This ensures we
-		 * are not violating security in doing the fchmod.
-		 */
-		files_struct *fsp;
-		if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname,
-				     &fsp)))
-			return -1;
-		become_root();
-		ret = SMB_VFS_FCHMOD(fsp, unixmode);
-		unbecome_root();
-		close_file(NULL, fsp, NORMAL_CLOSE);
-		if (!newfile) {
-			notify_fname(conn, NOTIFY_ACTION_MODIFIED,
-				     FILE_NOTIFY_CHANGE_ATTRIBUTES,
-				     smb_fname->base_name);
-		}
-		if (ret == 0) {
-			smb_fname->st.st_ex_mode = unixmode;
-		}
+	/*
+	 * We need to open the file with write access whilst
+	 * still in our current user context. This ensures we
+	 * are not violating security in doing the fchmod.
+	 */
+	if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname,
+			     &fsp)))
+		return -1;
+	become_root();
+	ret = SMB_VFS_FCHMOD(fsp, unixmode);
+	unbecome_root();
+	close_file(NULL, fsp, NORMAL_CLOSE);
+	if (!newfile) {
+		notify_fname(conn, NOTIFY_ACTION_MODIFIED,
+			     FILE_NOTIFY_CHANGE_ATTRIBUTES,
+			     smb_fname->base_name);
+	}
+	if (ret == 0) {
+		smb_fname->st.st_ex_mode = unixmode;
 	}
 
 	return( ret );
-- 
1.8.2.1


From 2feabb734776499cd7ccff7d294fde42a4bf0d07 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 Apr 2013 14:02:24 -0700
Subject: [PATCH 3/4] Ensure we don't try the open_file_fchmod() if we can't
 write to the file.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/dosmode.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 1fb0088..4a34947 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -856,6 +856,11 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 		bits on a file. Just like file_ntimes below.
 	*/
 
+	if (!can_write_to_file(conn, smb_fname)) {
+		errno = EACCES;
+		return -1;
+	}
+
 	/*
 	 * We need to open the file with write access whilst
 	 * still in our current user context. This ensures we
-- 
1.8.2.1


From 51d9b33d96034940280d0fc11a511c863e8203a6 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 Apr 2013 14:06:03 -0700
Subject: [PATCH 4/4] Check for WRITE_ACCESS on the file before overriding an
 EACCESS.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/dosmode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 4a34947..b534626 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -417,6 +417,10 @@ static bool set_ea_dos_attribute(connection_struct *conn,
 		if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
 			return false;
 
+		if (!can_write_to_file(conn, smb_fname)) {
+			return false;
+		}
+
 		/*
 		 * We need to open the file with write access whilst
 		 * still in our current user context. This ensures we
-- 
1.8.2.1



More information about the samba-technical mailing list