Commit ddfbc9bb authored by Evgeny Sinelnikov's avatar Evgeny Sinelnikov

Update sources 2.6.29 from 2.6.29.5

Fix unicode string area word alignment in session setup commit 5a12457e62aab1e19aa1b1d9bdbe53f26e9ed689 Fix buffer size in cifs_convertUCSpath commit a7a7d2fe8813c3bee7d7db9ba889fc2c2dd39dd7 Fix incorrect destination buffer size in cifs_strncpy_to_host commit 9381701c0f0722ffc1dab1c55ecd48f6d0b5be6f Increase size of tmp_buf in cifs_readdir to avoid potential overflows commit e9012cf5e92b7812f5fc88fdd1ddaecc34a5b904 Fix buffer size for tcon->nativeFileSystem field commit 5b0ecf297e133be1e4767b1e446a6d7902274c13
parent 4e1a01f1
...@@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); ...@@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
#endif #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 * UniStrcat: Concatenate the second string to the first
* *
* Returns: * Returns:
......
...@@ -91,23 +91,22 @@ static int ...@@ -91,23 +91,22 @@ static int
cifs_strncpy_to_host(char **dst, const char *src, const int maxlen, cifs_strncpy_to_host(char **dst, const char *src, const int maxlen,
const bool is_unicode, const struct nls_table *nls_codepage) const bool is_unicode, const struct nls_table *nls_codepage)
{ {
int plen; int src_len, dst_len;
if (is_unicode) { if (is_unicode) {
plen = UniStrnlen((wchar_t *)src, maxlen); src_len = UniStrnlen((wchar_t *)src, maxlen);
*dst = kmalloc(plen + 2, GFP_KERNEL); *dst = kmalloc((4 * src_len) + 2, GFP_KERNEL);
if (!*dst) if (!*dst)
goto cifs_strncpy_to_host_ErrExit; 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 { } else {
plen = strnlen(src, maxlen); src_len = strnlen(src, maxlen);
*dst = kmalloc(plen + 2, GFP_KERNEL); *dst = kmalloc(src_len + 1, GFP_KERNEL);
if (!*dst) if (!*dst)
goto cifs_strncpy_to_host_ErrExit; 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; return 0;
cifs_strncpy_to_host_ErrExit: cifs_strncpy_to_host_ErrExit:
......
...@@ -3673,16 +3673,12 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3673,16 +3673,12 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
BCC(smb_buffer_response)) { BCC(smb_buffer_response)) {
kfree(tcon->nativeFileSystem); kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem = tcon->nativeFileSystem =
kzalloc(2*(length + 1), GFP_KERNEL); kzalloc((4 * length) + 2, GFP_KERNEL);
if (tcon->nativeFileSystem) if (tcon->nativeFileSystem)
cifs_strfromUCS_le( cifs_strfromUCS_le(
tcon->nativeFileSystem, tcon->nativeFileSystem,
(__le16 *) bcc_ptr, (__le16 *) bcc_ptr,
length, nls_codepage); 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 do not bother copying these information fields*/
} else { } else {
......
...@@ -691,14 +691,15 @@ cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, ...@@ -691,14 +691,15 @@ cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
NLS_MAX_CHARSET_SIZE); NLS_MAX_CHARSET_SIZE);
if (len > 0) { if (len > 0) {
j += len; j += len;
continue; goto overrun_chk;
} else { } else {
target[j] = '?'; target[j] = '?';
} }
} }
j++; j++;
/* make sure we do not overrun callers allocated temp buffer */ /* make sure we do not overrun callers allocated temp buffer */
if (j >= (2 * NAME_MAX)) overrun_chk:
if (j >= UNICODE_NAME_MAX)
break; break;
} }
cUCS_out: cUCS_out:
......
...@@ -1072,7 +1072,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1072,7 +1072,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
with the rare long characters alloc more to account for with the rare long characters alloc more to account for
such multibyte target UTF-8 characters. cifs_unicode.c, such multibyte target UTF-8 characters. cifs_unicode.c,
which actually does the conversion, has the same limit */ 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++) { for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
if (current_entry == NULL) { if (current_entry == NULL) {
/* evaluate whether this case is an error */ /* evaluate whether this case is an error */
......
...@@ -111,7 +111,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses) ...@@ -111,7 +111,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
get_vc_num_exit: get_vc_num_exit:
write_unlock(&cifs_tcp_ses_lock); write_unlock(&cifs_tcp_ses_lock);
return le16_to_cpu(vcnum); return cpu_to_le16(vcnum);
} }
static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
...@@ -285,27 +285,26 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, ...@@ -285,27 +285,26 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
int words_left, len; int words_left, len;
char *data = *pbcc_area; char *data = *pbcc_area;
cFYI(1, ("bleft %d", bleft)); cFYI(1, ("bleft %d", bleft));
/*
/* SMB header is unaligned, so cifs servers word align start of * Windows servers do not always double null terminate their final
Unicode strings */ * Unicode string. Check to see if there are an uneven number of bytes
data++; * left. If so, then add an extra NULL pad byte to the end of the
bleft--; /* Windows servers do not always double null terminate * response.
their final Unicode string - in which case we *
now will not attempt to decode the byte of junk * See section 2.7.2 in "Implementing CIFS" for details
which follows it */ */
if (bleft % 2) {
data[bleft] = 0;
++bleft;
}
words_left = bleft / 2; words_left = bleft / 2;
/* save off server operating system */ /* save off server operating system */
len = UniStrnlen((wchar_t *) data, words_left); 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) if (len >= words_left)
return rc; return rc;
...@@ -343,13 +342,10 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, ...@@ -343,13 +342,10 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
return rc; return rc;
kfree(ses->serverDomain); kfree(ses->serverDomain);
ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL);
if (ses->serverDomain != NULL) { if (ses->serverDomain != NULL)
cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
nls_cp); nls_cp);
ses->serverDomain[2*len] = 0;
ses->serverDomain[(2*len) + 1] = 0;
}
data += 2 * (len + 1); data += 2 * (len + 1);
words_left -= len + 1; words_left -= len + 1;
...@@ -702,12 +698,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, ...@@ -702,12 +698,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
} }
/* BB check if Unicode and decode strings */ /* 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, rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
ses, nls_cp); ses, nls_cp);
else } else {
rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
ses, nls_cp); ses, nls_cp);
}
ssetup_exit: ssetup_exit:
if (spnego_key) { if (spnego_key) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment