aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/sess.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 5c68b4282be9..70d04d08293b 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -285,27 +285,26 @@ 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
@@ -343,13 +342,10 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
343 return rc; 342 return rc;
344 343
345 kfree(ses->serverDomain); 344 kfree(ses->serverDomain);
346 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 345 ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL);
347 if (ses->serverDomain != NULL) { 346 if (ses->serverDomain != NULL)
348 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 347 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
349 nls_cp); 348 nls_cp);
350 ses->serverDomain[2*len] = 0;
351 ses->serverDomain[(2*len) + 1] = 0;
352 }
353 data += 2 * (len + 1); 349 data += 2 * (len + 1);
354 words_left -= len + 1; 350 words_left -= len + 1;
355 351
@@ -702,12 +698,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
702 } 698 }
703 699
704 /* BB check if Unicode and decode strings */ 700 /* BB check if Unicode and decode strings */
705 if (smb_buf->Flags2 & SMBFLG2_UNICODE) 701 if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
702 /* unicode string area must be word-aligned */
703 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
704 ++bcc_ptr;
705 --bytes_remaining;
706 }
706 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 707 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
707 ses, nls_cp); 708 ses, nls_cp);
708 else 709 } else {
709 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, 710 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
710 ses, nls_cp); 711 ses, nls_cp);
712 }
711 713
712ssetup_exit: 714ssetup_exit:
713 if (spnego_key) { 715 if (spnego_key) {