[kernel] r13669 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Tue May 26 05:49:46 UTC 2009


Author: dannf
Date: Tue May 26 05:49:44 2009
New Revision: 13669

Log:
cifs: fix several string conversion issues (CVE-2009-1633)

Added:
   dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch
   dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch
   dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-rename-cifs_strncpy_to_host-and-fix-buffer-size.patch
Modified:
   dists/lenny-security/linux-2.6/debian/changelog
   dists/lenny-security/linux-2.6/debian/patches/series/15lenny3

Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog	Mon May 25 16:57:57 2009	(r13668)
+++ dists/lenny-security/linux-2.6/debian/changelog	Tue May 26 05:49:44 2009	(r13669)
@@ -5,6 +5,7 @@
   * xen: Fix missing check of interrupted code's code selector
     (CVE-2009-1758)
   * nfs4: fix MAY_EXEC handling (CVE-2009-1630)
+  * cifs: fix several string conversion issues (CVE-2009-1633)
 
  -- dann frazier <dannf at debian.org>  Thu, 21 May 2009 09:20:47 -0600
 

Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch	Tue May 26 05:49:44 2009	(r13669)
@@ -0,0 +1,116 @@
+commit 27b87fe52baba0a55e9723030e76fce94fabcea4
+Author: Jeff Layton <jlayton at redhat.com>
+Date:   Tue Apr 14 11:00:53 2009 -0400
+
+    cifs: fix unicode string area word alignment in session setup
+    
+    The handling of unicode string area alignment is wrong.
+    decode_unicode_ssetup improperly assumes that it will always be preceded
+    by a pad byte. This isn't the case if the string area is already
+    word-aligned.
+    
+    This problem, combined with the bad buffer sizing for the serverDomain
+    string can cause memory corruption. The bad alignment can make it so
+    that the alignment of the characters is off. This can make them
+    translate to characters that are greater than 2 bytes each. If this
+    happens we can overflow the allocation.
+    
+    Fix this by fixing the alignment in CIFS_SessSetup instead so we can
+    verify it against the head of the response. Also, clean up the
+    workaround for improperly terminated strings by checking for a
+    odd-length unicode buffers and then forcibly terminating them.
+    
+    Finally, resize the buffer for serverDomain. Now that we've fixed
+    the alignment, it's probably fine, but a malicious server could
+    overflow it.
+    
+    A better solution for handling these strings is still needed, but
+    this should be a suitable bandaid.
+    
+    Signed-off-by: Jeff Layton <jlayton at redhat.com>
+    CC: Stable <stable at vger.kernel.org>
+    Signed-off-by: Steve French <sfrench at us.ibm.com>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/fs/cifs/sess.c linux-source-2.6.26/fs/cifs/sess.c
+--- linux-source-2.6.26.orig/fs/cifs/sess.c	2009-05-11 12:06:56.000000000 -0600
++++ linux-source-2.6.26/fs/cifs/sess.c	2009-05-25 23:24:01.000000000 -0600
+@@ -202,27 +202,26 @@ static int decode_unicode_ssetup(char **
+ 	int words_left, len;
+ 	char *data = *pbcc_area;
+ 
+-
+-
+ 	cFYI(1, ("bleft %d", bleft));
+ 
+-
+-	/* SMB header is unaligned, so cifs servers word align start of
+-	   Unicode strings */
+-	data++;
+-	bleft--; /* Windows servers do not always double null terminate
+-		    their final Unicode string - in which case we
+-		    now will not attempt to decode the byte of junk
+-		    which follows it */
++	/*
++	 * Windows servers do not always double null terminate their final
++	 * Unicode string. Check to see if there are an uneven number of bytes
++	 * left. If so, then add an extra NULL pad byte to the end of the
++	 * response.
++	 *
++	 * See section 2.7.2 in "Implementing CIFS" for details
++	 */
++	if (bleft % 2) {
++		data[bleft] = 0;
++		++bleft;
++	}
+ 
+ 	words_left = bleft / 2;
+ 
+ 	/* save off server operating system */
+ 	len = UniStrnlen((wchar_t *) data, words_left);
+ 
+-/* We look for obvious messed up bcc or strings in response so we do not go off
+-   the end since (at least) WIN2K and Windows XP have a major bug in not null
+-   terminating last Unicode string in response  */
+ 	if (len >= words_left)
+ 		return rc;
+ 
+@@ -260,13 +259,10 @@ static int decode_unicode_ssetup(char **
+ 		return rc;
+ 
+ 	kfree(ses->serverDomain);
+-	ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
+-	if (ses->serverDomain != NULL) {
++	ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL);
++	if (ses->serverDomain != NULL)
+ 		cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
+ 				   nls_cp);
+-		ses->serverDomain[2*len] = 0;
+-		ses->serverDomain[(2*len) + 1] = 0;
+-	}
+ 	data += 2 * (len + 1);
+ 	words_left -= len + 1;
+ 
+@@ -605,12 +601,18 @@ CIFS_SessSetup(unsigned int xid, struct 
+ 	}
+ 
+ 	/* BB check if Unicode and decode strings */
+-	if (smb_buf->Flags2 & SMBFLG2_UNICODE)
++	if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
++		/* unicode string area must be word-aligned */
++		if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
++			++bcc_ptr;
++			--bytes_remaining;
++		}
+ 		rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
+-						   ses, nls_cp);
+-	else
++					   ses, nls_cp);
++	} else {
+ 		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
+ 					 ses, nls_cp);
++	}
+ 
+ ssetup_exit:
+ 	if (spnego_key)

Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch	Tue May 26 05:49:44 2009	(r13669)
@@ -0,0 +1,27 @@
+commit 7b0c8fcff47a885743125dd843db64af41af5a61
+Author: Suresh Jayaraman <sjayaraman at suse.de>
+Date:   Mon Apr 20 18:54:36 2009 +0530
+
+    cifs: Increase size of tmp_buf in cifs_readdir to avoid potential overflows
+    
+    Increase size of tmp_buf to possible maximum to avoid potential
+    overflows.
+    
+    Pointed-out-by: Jeff Layton <jlayton at redhat.com>
+    Signed-off-by: Suresh Jayaraman <sjayaraman at suse.de>
+    Acked-by: Jeff Layton <jlayton at redhat.com>
+    Signed-off-by: Steve French <sfrench at us.ibm.com>
+
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 1a8be62..ebd0da7 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -1074,7 +1074,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
+ 		with the rare long characters alloc more to account for
+ 		such multibyte target UTF-8 characters. cifs_unicode.c,
+ 		which actually does the conversion, has the same limit */
+-		tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
++		tmp_buf = kmalloc((4 * NAME_MAX) + 2, GFP_KERNEL);
+ 		for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
+ 			if (current_entry == NULL) {
+ 				/* evaluate whether this case is an error */

Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-rename-cifs_strncpy_to_host-and-fix-buffer-size.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/cifs-rename-cifs_strncpy_to_host-and-fix-buffer-size.patch	Tue May 26 05:49:44 2009	(r13669)
@@ -0,0 +1,79 @@
+commit 968460ebd8006d55661dec0fb86712b40d71c413
+Author: Suresh Jayaraman <sjayaraman at suse.de>
+Date:   Mon Apr 20 18:54:21 2009 +0530
+
+    cifs: Rename cifs_strncpy_to_host and fix buffer size
+    
+    There is a possibility for the path_name and node_name buffers to
+    overflow if they contain charcters that are >2 bytes in the local
+    charset. Resize the buffer allocation so to avoid this possibility.
+    
+    Also, as pointed out by Jeff Layton, it would be appropriate to
+    rename the function to cifs_strlcpy_to_host to reflect the fact
+    that the copied string is always NULL terminated.
+    
+    Signed-off-by: Suresh Jayaraman <sjayaraman at suse.de>
+    Acked-by: Jeff Layton <jlayton at redhat.com>
+    Signed-off-by: Steve French <sfrench at us.ibm.com>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/fs/cifs/cifssmb.c linux-source-2.6.26/fs/cifs/cifssmb.c
+--- linux-source-2.6.26.orig/fs/cifs/cifssmb.c	2009-05-11 12:06:53.000000000 -0600
++++ linux-source-2.6.26/fs/cifs/cifssmb.c	2009-05-25 23:30:32.000000000 -0600
+@@ -88,29 +88,29 @@ static struct {
+  *	on failure - errno
+  */
+ static int
+-cifs_strncpy_to_host(char **dst, const char *src, const int maxlen,
++cifs_strlcpy_to_host(char **dst, const char *src, const int maxlen,
+ 		 const bool is_unicode, const struct nls_table *nls_codepage)
+ {
+ 	int plen;
+ 
+ 	if (is_unicode) {
+ 		plen = UniStrnlen((wchar_t *)src, maxlen);
+-		*dst = kmalloc(plen + 2, GFP_KERNEL);
++		*dst = kmalloc((4 * plen) + 2, GFP_KERNEL);
+ 		if (!*dst)
+-			goto cifs_strncpy_to_host_ErrExit;
++			goto cifs_strlcpy_to_host_ErrExit;
+ 		cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage);
++		(*dst)[plen] = 0;
++		(*dst)[plen+1] = 0; /* needed for Unicode */
+ 	} else {
+ 		plen = strnlen(src, maxlen);
+ 		*dst = kmalloc(plen + 2, GFP_KERNEL);
+ 		if (!*dst)
+-			goto cifs_strncpy_to_host_ErrExit;
+-		strncpy(*dst, src, plen);
++			goto cifs_strlcpy_to_host_ErrExit;
++		strlcpy(*dst, src, plen);
+ 	}
+-	(*dst)[plen] = 0;
+-	(*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */
+ 	return 0;
+ 
+-cifs_strncpy_to_host_ErrExit:
++cifs_strlcpy_to_host_ErrExit:
+ 	cERROR(1, ("Failed to allocate buffer for string\n"));
+ 	return -ENOMEM;
+ }
+@@ -3966,7 +3966,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS
+ 		/* copy DfsPath */
+ 		temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
+ 		max_len = data_end - temp;
+-		rc = cifs_strncpy_to_host(&(node->path_name), temp,
++		rc = cifs_strlcpy_to_host(&(node->path_name), temp,
+ 					max_len, is_unicode, nls_codepage);
+ 		if (rc)
+ 			goto parse_DFS_referrals_exit;
+@@ -3974,7 +3974,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS
+ 		/* copy link target UNC */
+ 		temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
+ 		max_len = data_end - temp;
+-		rc = cifs_strncpy_to_host(&(node->node_name), temp,
++		rc = cifs_strlcpy_to_host(&(node->node_name), temp,
+ 					max_len, is_unicode, nls_codepage);
+ 		if (rc)
+ 			goto parse_DFS_referrals_exit;

Modified: dists/lenny-security/linux-2.6/debian/patches/series/15lenny3
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/15lenny3	Mon May 25 16:57:57 2009	(r13668)
+++ dists/lenny-security/linux-2.6/debian/patches/series/15lenny3	Tue May 26 05:49:44 2009	(r13669)
@@ -1,2 +1,5 @@
 + bugfix/all/unreached-code-in-selinux_ip_postroute_iptables_compat-2.patch
 + bugfix/all/nfs-v4-client-fix-MAY_EXEC-handling.patch
++ bugfix/all/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch
++ bugfix/all/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch
++ bugfix/all/cifs-rename-cifs_strncpy_to_host-and-fix-buffer-size.patch



More information about the Kernel-svn-changes mailing list