aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r--fs/cifs/sess.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 5c68b4282be9..c652c73760dd 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -285,35 +285,36 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
285 int words_left, len; 285 int words_left, len;
286 char *data = *pbcc_area; 286 char *data = *pbcc_area;
287 287
288
289
290 cFYI(1, ("bleft %d", bleft)); 288 cFYI(1, ("bleft %d", bleft));
291 289
292 290 /*
293 /* SMB header is unaligned, so cifs servers word align start of 291 * Windows servers do not always double null terminate their final
294 Unicode strings */ 292 * Unicode string. Check to see if there are an uneven number of bytes
295 data++; 293 * left. If so, then add an extra NULL pad byte to the end of the
296 bleft--; /* Windows servers do not always double null terminate 294 * response.
297 their final Unicode string - in which case we 295 *
298 now will not attempt to decode the byte of junk 296 * See section 2.7.2 in "Implementing CIFS" for details
299 which follows it */ 297 */
298 if (bleft % 2) {
299 data[bleft] = 0;
300 ++bleft;
301 }
300 302
301 words_left = bleft / 2; 303 words_left = bleft / 2;
302 304
303 /* save off server operating system */ 305 /* save off server operating system */
304 len = UniStrnlen((wchar_t *) data, words_left); 306 len = UniStrnlen((wchar_t *) data, words_left);
305 307
306/* We look for obvious messed up bcc or strings in response so we do not go off
307 the end since (at least) WIN2K and Windows XP have a major bug in not null
308 terminating last Unicode string in response */
309 if (len >= words_left) 308 if (len >= words_left)
310 return rc; 309 return rc;
311 310
312 kfree(ses->serverOS); 311 kfree(ses->serverOS);
313 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 312 /* UTF-8 string will not grow more than four times as big as UCS-16 */
314 ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); 313 ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL);
315 if (ses->serverOS != NULL) 314 if (ses->serverOS != NULL) {
316 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); 315 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
316 cFYI(1, ("serverOS=%s", ses->serverOS));
317 }
317 data += 2 * (len + 1); 318 data += 2 * (len + 1);
318 words_left -= len + 1; 319 words_left -= len + 1;
319 320
@@ -328,6 +329,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
328 if (ses->serverNOS != NULL) { 329 if (ses->serverNOS != NULL) {
329 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 330 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
330 nls_cp); 331 nls_cp);
332 cFYI(1, ("serverNOS=%s", ses->serverNOS));
331 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) { 333 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
332 cFYI(1, ("NT4 server")); 334 cFYI(1, ("NT4 server"));
333 ses->flags |= CIFS_SES_NT4; 335 ses->flags |= CIFS_SES_NT4;
@@ -343,12 +345,11 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
343 return rc; 345 return rc;
344 346
345 kfree(ses->serverDomain); 347 kfree(ses->serverDomain);
346 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 348 ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL);
347 if (ses->serverDomain != NULL) { 349 if (ses->serverDomain != NULL) {
348 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 350 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
349 nls_cp); 351 nls_cp);
350 ses->serverDomain[2*len] = 0; 352 cFYI(1, ("serverDomain=%s", ses->serverDomain));
351 ses->serverDomain[(2*len) + 1] = 0;
352 } 353 }
353 data += 2 * (len + 1); 354 data += 2 * (len + 1);
354 words_left -= len + 1; 355 words_left -= len + 1;
@@ -702,12 +703,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
702 } 703 }
703 704
704 /* BB check if Unicode and decode strings */ 705 /* BB check if Unicode and decode strings */
705 if (smb_buf->Flags2 & SMBFLG2_UNICODE) 706 if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
707 /* unicode string area must be word-aligned */
708 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
709 ++bcc_ptr;
710 --bytes_remaining;
711 }
706 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 712 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
707 ses, nls_cp); 713 ses, nls_cp);
708 else 714 } else {
709 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, 715 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
710 ses, nls_cp); 716 ses, nls_cp);
717 }
711 718
712ssetup_exit: 719ssetup_exit:
713 if (spnego_key) { 720 if (spnego_key) {