Commit b15efa95 authored by Evgeny Sinelnikov's avatar Evgeny Sinelnikov

Merge branch 'work'

parents 4d0edc96 ddfbc9bb
Fix oops in cifs_dfs_ref.c when prefixpath is not reachable when using DFS.
Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too
little memory for the "nativeFileSystem" field returned by the server
during mount).
Version 1.54
------------
......
......@@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
#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:
......
......@@ -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:
......@@ -2387,8 +2386,10 @@ winCreateHardLinkRetry:
PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0; /* pad */
pSMB->OldFileName[name_len + 1] = 0x04;
/* protocol specifies ASCII buffer format (0x04) for unicode */
pSMB->OldFileName[name_len] = 0x04;
pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
name_len2 =
cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
toName, PATH_MAX, nls_codepage, remap);
......
......@@ -3569,16 +3569,12 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
BCC(smb_buffer_response)) {
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, 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 {
......
......@@ -685,14 +685,15 @@ cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
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:
......
......@@ -1075,7 +1075,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(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 */
......
......@@ -202,27 +202,26 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
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 **pbcc_area, int bleft,
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 cifsSesInfo *ses, int first_time,
}
/* 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)
......
Fix oops in cifs_dfs_ref.c when prefixpath is not reachable when using DFS.
Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too
little memory for the "nativeFileSystem" field returned by the server
during mount).
Version 1.55
------------
......
......@@ -2389,8 +2389,10 @@ winCreateHardLinkRetry:
PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0; /* pad */
pSMB->OldFileName[name_len + 1] = 0x04;
/* protocol specifies ASCII buffer format (0x04) for unicode */
pSMB->OldFileName[name_len] = 0x04;
pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
name_len2 =
cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
toName, PATH_MAX, nls_codepage, remap);
......
......@@ -3585,7 +3585,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
BCC(smb_buffer_response)) {
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL);
kzalloc(2*(length + 1), GFP_KERNEL);
if (tcon->nativeFileSystem)
cifs_strfromUCS_le(
tcon->nativeFileSystem,
......
......@@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
#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:
......
......@@ -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:
......
......@@ -3673,16 +3673,12 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
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 {
......
......@@ -691,14 +691,15 @@ cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
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:
......
......@@ -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
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 */
......
......@@ -111,7 +111,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
get_vc_num_exit:
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)
......@@ -285,27 +285,26 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
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;
......@@ -343,13 +342,10 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
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;
......@@ -702,12 +698,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
}
/* 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) {
......
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