From: Greg Kroah-Hartman Date: Wed, 13 May 2009 04:58:35 +0000 (-0700) Subject: cifs patches for .27 X-Git-Tag: v2.6.29.4~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=97d029d9a1eea7e3ccf4a3d54051d87a2dfa8b45;p=thirdparty%2Fkernel%2Fstable-queue.git cifs patches for .27 --- diff --git a/queue-2.6.27/cifs-fix-buffer-size-for-tcon-nativefilesystem-field.patch b/queue-2.6.27/cifs-fix-buffer-size-for-tcon-nativefilesystem-field.patch new file mode 100644 index 00000000000..16791873105 --- /dev/null +++ b/queue-2.6.27/cifs-fix-buffer-size-for-tcon-nativefilesystem-field.patch @@ -0,0 +1,53 @@ +From stable-bounces@linux.kernel.org Tue May 12 14:04:56 2009 +From: Suresh Jayaraman +Date: Sat, 09 May 2009 11:19:05 +0530 +Subject: cifs: Fix buffer size for tcon->nativeFileSystem field +To: stable@kernel.org +Cc: Steve French , Jeff Layton +Message-ID: <4A051951.5060801@suse.de> + + +From: Jeff Layton + +Commit f083def68f84b04fe3f97312498911afce79609e refreshed. + +cifs: fix buffer size for tcon->nativeFileSystem field + +The buffer for this was resized recently to fix a bug. It's still +possible however that a malicious server could overflow this field +by sending characters in it that are >2 bytes in the local charset. +Double the size of the buffer to account for this possibility. + +Also get rid of some really strange and seemingly pointless NULL +termination. It's NULL terminating the string in the source buffer, +but by the time that happens, we've already copied the string. + +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Cc: Suresh Jayaraman +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/connect.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -3549,16 +3549,12 @@ CIFSTCon(unsigned int xid, struct cifsSe + BCC(smb_buffer_response)) { + kfree(tcon->nativeFileSystem); + tcon->nativeFileSystem = +- kzalloc(2*(length + 1), GFP_KERNEL); ++ kzalloc((4 * length) + 2, GFP_KERNEL); + if (tcon->nativeFileSystem) + cifs_strfromUCS_le( + tcon->nativeFileSystem, + (__le16 *) bcc_ptr, + length, nls_codepage); +- bcc_ptr += 2 * length; +- bcc_ptr[0] = 0; /* null terminate the string */ +- bcc_ptr[1] = 0; +- bcc_ptr += 2; + } + /* else do not bother copying these information fields*/ + } else { diff --git a/queue-2.6.27/cifs-fix-buffer-size-in-cifs_convertucspath.patch b/queue-2.6.27/cifs-fix-buffer-size-in-cifs_convertucspath.patch new file mode 100644 index 00000000000..733c8cea55e --- /dev/null +++ b/queue-2.6.27/cifs-fix-buffer-size-in-cifs_convertucspath.patch @@ -0,0 +1,46 @@ +From stable-bounces@linux.kernel.org Tue May 12 14:06:17 2009 +From: Suresh Jayaraman +Date: Sat, 09 May 2009 11:33:12 +0530 +Subject: cifs: Fix buffer size in cifs_convertUCSpath +To: stable@kernel.org +Cc: Steve French , Jeff Layton +Message-ID: <4A051CA0.6010401@suse.de> + + +From: Suresh Jayaraman + +Relevant commits 7fabf0c9479fef9fdb9528a5fbdb1cb744a744a4 and +f58841666bc22e827ca0dcef7b71c7bc2758ce82. The upstream commits adds +cifs_from_ucs2 that includes functionality of cifs_convertUCSpath and +does cleanup. + +Reported-by: Jeff Layton +Signed-off-by: Suresh Jayaraman +Acked-by: Steve French +Acked-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/misc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -685,14 +685,15 @@ cifs_convertUCSpath(char *target, const + NLS_MAX_CHARSET_SIZE); + if (len > 0) { + j += len; +- continue; ++ goto overrun_chk; + } else { + target[j] = '?'; + } + } + j++; + /* make sure we do not overrun callers allocated temp buffer */ +- if (j >= (2 * NAME_MAX)) ++overrun_chk: ++ if (j >= UNICODE_NAME_MAX) + break; + } + cUCS_out: diff --git a/queue-2.6.27/cifs-fix-incorrect-destination-buffer-size-in-cifs_strncpy_to_host.patch b/queue-2.6.27/cifs-fix-incorrect-destination-buffer-size-in-cifs_strncpy_to_host.patch new file mode 100644 index 00000000000..938f7ddeba6 --- /dev/null +++ b/queue-2.6.27/cifs-fix-incorrect-destination-buffer-size-in-cifs_strncpy_to_host.patch @@ -0,0 +1,70 @@ +From stable-bounces@linux.kernel.org Tue May 12 14:05:52 2009 +From: Suresh Jayaraman +Date: Sat, 09 May 2009 11:26:44 +0530 +Subject: cifs: Fix incorrect destination buffer size in cifs_strncpy_to_host +To: stable@kernel.org +Cc: Steve French , Jeff Layton +Message-ID: <4A051B1C.4030606@suse.de> + + +From: Suresh Jayaraman + + +Relevant commits 968460ebd8006d55661dec0fb86712b40d71c413 and +066ce6899484d9026acd6ba3a8dbbedb33d7ae1b. Minimal hunks to fix buffer +size and fix an existing problem pointed out by Guenter Kukuk that length +of src is used for NULL termination of dst. + +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 +Acked-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifssmb.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -91,23 +91,22 @@ static int + cifs_strncpy_to_host(char **dst, const char *src, const int maxlen, + const bool is_unicode, const struct nls_table *nls_codepage) + { +- int plen; ++ int src_len, dst_len; + + if (is_unicode) { +- plen = UniStrnlen((wchar_t *)src, maxlen); +- *dst = kmalloc(plen + 2, GFP_KERNEL); ++ src_len = UniStrnlen((wchar_t *)src, maxlen); ++ *dst = kmalloc((4 * src_len) + 2, GFP_KERNEL); + if (!*dst) + goto cifs_strncpy_to_host_ErrExit; +- cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage); ++ dst_len = cifs_strfromUCS_le(*dst, (__le16 *)src, src_len, nls_codepage); ++ (*dst)[dst_len + 1] = 0; + } else { +- plen = strnlen(src, maxlen); +- *dst = kmalloc(plen + 2, GFP_KERNEL); ++ src_len = strnlen(src, maxlen); ++ *dst = kmalloc(src_len + 1, GFP_KERNEL); + if (!*dst) + goto cifs_strncpy_to_host_ErrExit; +- strncpy(*dst, src, plen); ++ strlcpy(*dst, src, src_len + 1); + } +- (*dst)[plen] = 0; +- (*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */ + return 0; + + cifs_strncpy_to_host_ErrExit: diff --git a/queue-2.6.27/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch b/queue-2.6.27/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch new file mode 100644 index 00000000000..097850d2552 --- /dev/null +++ b/queue-2.6.27/cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch @@ -0,0 +1,127 @@ +From stable-bounces@linux.kernel.org Tue May 12 14:06:45 2009 +From: Jeff Layton +Date: Sat, 09 May 2009 11:34:21 +0530 +Subject: cifs: Fix unicode string area word alignment in session setup +To: stable@kernel.org +Cc: Steve French , Jeff Layton +Message-ID: <4A051CE5.6040203@suse.de> + + +From: Jeff Layton + +commit 27b87fe52baba0a55e9723030e76fce94fabcea4 refreshed. + +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 +Signed-off-by: Steve French +Cc: Suresh Jayaraman +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/sess.c | 44 +++++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -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; + +@@ -616,12 +612,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) diff --git a/queue-2.6.27/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch b/queue-2.6.27/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch new file mode 100644 index 00000000000..7b3add6ab43 --- /dev/null +++ b/queue-2.6.27/cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch @@ -0,0 +1,58 @@ +From stable-bounces@linux.kernel.org Tue May 12 14:05:28 2009 +From: Suresh Jayaraman +Date: Sat, 09 May 2009 11:22:47 +0530 +Subject: cifs: Increase size of tmp_buf in cifs_readdir to avoid potential overflows +To: stable@kernel.org +Cc: Steve French , Jeff Layton +Message-ID: <4A051A2F.50308@suse.de> + + +From: Suresh Jayaraman + +Commit 7b0c8fcff47a885743125dd843db64af41af5a61 refreshed and use +a #define from commit f58841666bc22e827ca0dcef7b71c7bc2758ce82. + +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. Also moved UNICODE_NAME_MAX definition so that it can be used +elsewhere. + +Pointed-out-by: Jeff Layton +Signed-off-by: Suresh Jayaraman +Acked-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifs_unicode.h | 7 +++++++ + fs/cifs/readdir.c | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/cifs/cifs_unicode.h ++++ b/fs/cifs/cifs_unicode.h +@@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char * + #endif + + /* ++ * To be safe - for UCS to UTF-8 with strings loaded with the rare long ++ * characters alloc more to account for such multibyte target UTF-8 ++ * characters. ++ */ ++#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2) ++ ++/* + * UniStrcat: Concatenate the second string to the first + * + * Returns: +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -1075,7 +1075,7 @@ int cifs_readdir(struct file *file, void + 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(UNICODE_NAME_MAX, GFP_KERNEL); + for (i = 0; (i < num_to_fill) && (rc == 0); i++) { + if (current_entry == NULL) { + /* evaluate whether this case is an error */ diff --git a/queue-2.6.27/series b/queue-2.6.27/series index ad07d363b6b..6dd69ab5baa 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -12,3 +12,8 @@ mm-close-page_mkwrite-races.patch gfs2-fix-page_mkwrite-return-code.patch nfs-fix-the-return-value-in-nfs_page_mkwrite.patch nfs-close-page_mkwrite-races.patch +cifs-fix-buffer-size-for-tcon-nativefilesystem-field.patch +cifs-increase-size-of-tmp_buf-in-cifs_readdir-to-avoid-potential-overflows.patch +cifs-fix-incorrect-destination-buffer-size-in-cifs_strncpy_to_host.patch +cifs-fix-buffer-size-in-cifs_convertucspath.patch +cifs-fix-unicode-string-area-word-alignment-in-session-setup.patch