[SCM] SAMBA-CTDB repository - branch v3-2-ctdb updated - 3.2.11-ctdb-69-4-g221c557

Michael Adam obnox at samba.org
Fri Jan 22 03:46:05 MST 2010


The branch, v3-2-ctdb has been updated
       via  221c557f1fa0709cb5fc0c46ca5abcc480553a23 (commit)
       via  4c58bbfd8488bfe88be8a304182c2e02b2f39dc1 (commit)
       via  51d5d9e6f75e64b0947d47a91f07861be5b1e126 (commit)
      from  f957e56ae7b041abc15e5fadc3847da6ca80aece (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-2-ctdb


- Log -----------------------------------------------------------------
commit 221c557f1fa0709cb5fc0c46ca5abcc480553a23
Author: Jeff Layton <jlayton at redhat.com>
Date:   Fri Sep 25 07:03:44 2009 -0400

    mount.cifs: don't leak passwords with verbose option
    
    When running mount.cifs with the --verbose option, it'll print out the
    option string that it passes to the kernel...including the mount
    password if there is one. Print a placeholder string instead to help
    ensure that this info can't be used for nefarious purposes.
    
    Also, the --verbose option printed the option string before it was
    completely assembled anyway. This patch should also make sure that
    the complete option string is printed out.
    
    Finally, strndup passwords passed in on the command line to ensure that
    they aren't shown by --verbose as well. Passwords used this way can
    never be truly kept private from other users on the machine of course,
    but it's simple enough to do it this way for completeness sake.
    
    Reported-by: Ronald Volgers <r.c.volgers at student.utwente.nl>
    Signed-off-by: Jeff Layton <jlayton at redhat.com>
    Acked-by: Steve French <sfrench at us.ibm.com>
    Signed-off-by: Christian Ambach <christian.ambach at de.ibm.com>

commit 4c58bbfd8488bfe88be8a304182c2e02b2f39dc1
Author: Jeff Layton <jlayton at redhat.com>
Date:   Fri Sep 25 07:03:44 2009 -0400

    mount.cifs: check access of credential files before opening
    
    It's possible for an unprivileged user to pass a setuid mount.cifs a
    credential or password file to which he does not have access. This can cause
    mount.cifs to open the file on his behalf and possibly leak the info in the
    first few lines of the file.
    
    Check the access permissions of the file before opening it.
    
    Reported-by: Ronald Volgers <r.c.volgers at student.utwente.nl>
    Signed-off-by: Jeff Layton <jlayton at redhat.com>
    Acked-by: Steve French <sfrench at us.ibm.com>
    Signed-off-by: Christian Ambach <christian.ambach at de.ibm.com>

commit 51d5d9e6f75e64b0947d47a91f07861be5b1e126
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Sep 30 14:24:50 2009 +0200

    Fix for CVE-2009-2906.
    
    Summary:
    Specially crafted SMB requests on
    authenticated SMB connections can send smbd
    into a 100% CPU loop, causing a DoS on the
    Samba server.
    
    Signed-off-by: Christian Ambach <christian.ambach at de.ibm.com>

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

Summary of changes:
 source/client/mount.cifs.c |   65 ++++++++++++++++++++++++++++++-------------
 source/include/smb.h       |    1 +
 source/smbd/process.c      |   28 +++++++++++++++++--
 3 files changed, 71 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index d05115b..a947dd1 100644
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -199,6 +199,11 @@ static int open_cred_file(char * file_name)
 	char * temp_val;
 	FILE * fs;
 	int i, length;
+
+	i = access(file_name, R_OK);
+	if (i)
+		return i;
+
 	fs = fopen(file_name,"r");
 	if(fs == NULL)
 		return errno;
@@ -321,6 +326,12 @@ static int get_password_from_file(int file_descript, char * filename)
 	}
 
 	if(filename != NULL) {
+		rc = access(filename, R_OK);
+		if (rc) {
+			fprintf(stderr, "mount.cifs failed: access check of %s failed: %s\n",
+					filename, strerror(errno));
+			exit(EX_SYSERR);
+		}
 		file_descript = open(filename, O_RDONLY);
 		if(file_descript < 0) {
 			printf("mount.cifs failed. %s attempting to open password file %s\n",
@@ -380,9 +391,6 @@ static int parse_options(char ** optionsp, int * filesys_flags)
 		return 1;
 	data = *optionsp;
 
-	if(verboseflag)
-		printf("parsing options: %s\n", data);
-
 	/* BB fixme check for separator override BB */
 
 	if (getuid()) {
@@ -471,18 +479,27 @@ static int parse_options(char ** optionsp, int * filesys_flags)
 		} else if (strncmp(data, "pass", 4) == 0) {
 			if (!value || !*value) {
 				if(got_password) {
-					printf("\npassword specified twice, ignoring second\n");
+					fprintf(stderr, "\npassword specified twice, ignoring second\n");
 				} else
 					got_password = 1;
-			} else if (strnlen(value, 17) < 17) {
-				if(got_password)
-					printf("\nmount.cifs warning - password specified twice\n");
-				got_password = 1;
+			} else if (strnlen(value, MOUNT_PASSWD_SIZE) < MOUNT_PASSWD_SIZE) {
+				if (got_password) {
+					fprintf(stderr, "\nmount.cifs warning - password specified twice\n");
+				} else {
+					mountpassword = strndup(value, MOUNT_PASSWD_SIZE);
+					if (!mountpassword) {
+						fprintf(stderr, "mount.cifs error: %s", strerror(ENOMEM));
+						SAFE_FREE(out);
+						return 1;
+					}
+					got_password = 1;
+				}
 			} else {
-				printf("password too long\n");
+				fprintf(stderr, "password too long\n");
 				SAFE_FREE(out);
 				return 1;
 			}
+			goto nocopy;
 		} else if (strncmp(data, "sec", 3) == 0) {
 			if (value) {
 				if (!strncmp(value, "none", 4) ||
@@ -1370,15 +1387,6 @@ mount_retry:
 			strlcat(options,domain_name,options_size);
 		}
 	}
-	if(mountpassword) {
-		/* Commas have to be doubled, or else they will
-		look like the parameter separator */
-/*		if(sep is not set)*/
-		if(retry == 0)
-			check_for_comma(&mountpassword);
-		strlcat(options,",pass=",options_size);
-		strlcat(options,mountpassword,options_size);
-	}
 
 	strlcat(options,",ver=",options_size);
 	strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size);
@@ -1391,8 +1399,6 @@ mount_retry:
 		strlcat(options,",prefixpath=",options_size);
 		strlcat(options,prefixpath,options_size); /* no need to cat the / */
 	}
-	if(verboseflag)
-		printf("\nmount.cifs kernel mount options %s \n",options);
 
 	/* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */
 	replace_char(dev_name, '\\', '/', strlen(share_name));
@@ -1424,6 +1430,25 @@ mount_retry:
 		}
 	}
 
+	if(verboseflag)
+		fprintf(stderr, "\nmount.cifs kernel mount options: %s", options);
+
+	if (mountpassword) {
+		/*
+		 * Commas have to be doubled, or else they will
+		 * look like the parameter separator
+		 */
+		if(retry == 0)
+			check_for_comma(&mountpassword);
+		strlcat(options,",pass=",options_size);
+		strlcat(options,mountpassword,options_size);
+		if (verboseflag)
+			fprintf(stderr, ",pass=********");
+	}
+
+	if (verboseflag)
+		fprintf(stderr, "\n");
+
 	if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) {
 		switch (errno) {
 		case ECONNREFUSED:
diff --git a/source/include/smb.h b/source/include/smb.h
index dc346d8..960984f 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -759,6 +759,7 @@ struct pending_message_list {
 	struct timeval request_time; /* When was this first issued? */
 	struct timeval end_time; /* When does this time out? */
 	bool encrypted;
+	bool processed;
 	DATA_BLOB buf;
 	DATA_BLOB private_data;
 };
diff --git a/source/smbd/process.c b/source/smbd/process.c
index ad01a52..c53bfda 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -434,6 +434,7 @@ static bool push_queued_message(struct smb_request *req,
 	msg->request_time = request_time;
 	msg->end_time = end_time;
 	msg->encrypted = req->encrypted;
+	msg->processed = false;
 
 	if (private_data) {
 		msg->private_data = data_blob_talloc(msg, private_data,
@@ -489,6 +490,16 @@ void schedule_deferred_open_smb_message(uint16 mid)
 		DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
 			(unsigned int)msg_mid ));
 		if (mid == msg_mid) {
+
+			if (pml->processed) {
+				/* A processed message should not be
+				 * rescheduled. */
+				DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
+					"message mid %u was already processed\n",
+					(unsigned int)msg_mid ));
+				continue;
+			}
+
 			DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
 				mid ));
 			pml->end_time.tv_sec = 0;
@@ -503,7 +514,7 @@ void schedule_deferred_open_smb_message(uint16 mid)
 }
 
 /****************************************************************************
- Return true if this mid is on the deferred queue.
+ Return true if this mid is on the deferred queue and was not yet processed.
 ****************************************************************************/
 
 bool open_was_deferred(uint16 mid)
@@ -511,7 +522,7 @@ bool open_was_deferred(uint16 mid)
 	struct pending_message_list *pml;
 
 	for (pml = deferred_open_queue; pml; pml = pml->next) {
-		if (SVAL(pml->buf.data,smb_mid) == mid) {
+		if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
 			return True;
 		}
 	}
@@ -778,6 +789,10 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
 			/* We leave this message on the queue so the open code can
 			   know this is a retry. */
 			DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
+
+			/* Mark the message as processed so this is not
+			 * re-processed in error. */
+			msg->processed = true;
 			return NT_STATUS_OK;
 		}
 	}
@@ -1405,7 +1420,6 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
 
 		if (!change_to_user(conn,session_tag)) {
 			reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
-			remove_deferred_open_smb_message(req->mid);
 			return conn;
 		}
 
@@ -1470,6 +1484,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
 
 static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
 {
+	struct pending_message_list *pml = NULL;
 	uint8 type = CVAL(inbuf,smb_com);
 	connection_struct *conn;
 	struct smb_request *req;
@@ -1485,6 +1500,13 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
 
 	conn = switch_message(type, req, size);
 
+	/* If this was a deferred message and it's still there and
+	 * was processed, remove it. */
+	pml = get_open_deferred_message(req->mid);
+	if (pml && pml->processed) {
+		remove_deferred_open_smb_message(req->mid);
+	}
+
 	if (req->unread_bytes) {
 		/* writeX failed. drain socket. */
 		if (drain_socket(smbd_server_fd(), req->unread_bytes) !=


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list