Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: handle errors from coalesce_t2
cifs: refactor mid finding loop in cifs_demultiplex_thread
cifs: sanitize length checking in coalesce_t2 (try #3)
cifs: check for bytes_remaining going to zero in CIFS_SessSetup
cifs: change bleft in decode_unicode_ssetup back to signed type

+72 -69
+68 -54
fs/cifs/connect.c
··· 274 274 char *data_area_of_target; 275 275 char *data_area_of_buf2; 276 276 int remaining; 277 - __u16 byte_count, total_data_size, total_in_buf, total_in_buf2; 277 + unsigned int byte_count, total_in_buf; 278 + __u16 total_data_size, total_in_buf2; 278 279 279 280 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount); 280 281 ··· 288 287 remaining = total_data_size - total_in_buf; 289 288 290 289 if (remaining < 0) 291 - return -EINVAL; 290 + return -EPROTO; 292 291 293 292 if (remaining == 0) /* nothing to do, ignore */ 294 293 return 0; ··· 309 308 data_area_of_target += total_in_buf; 310 309 311 310 /* copy second buffer into end of first buffer */ 312 - memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); 313 311 total_in_buf += total_in_buf2; 312 + /* is the result too big for the field? */ 313 + if (total_in_buf > USHRT_MAX) 314 + return -EPROTO; 314 315 put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount); 316 + 317 + /* fix up the BCC */ 315 318 byte_count = get_bcc_le(pTargetSMB); 316 319 byte_count += total_in_buf2; 320 + /* is the result too big for the field? */ 321 + if (byte_count > USHRT_MAX) 322 + return -EPROTO; 317 323 put_bcc_le(byte_count, pTargetSMB); 318 324 319 325 byte_count = pTargetSMB->smb_buf_length; 320 326 byte_count += total_in_buf2; 321 - 322 - /* BB also add check that we are not beyond maximum buffer size */ 323 - 327 + /* don't allow buffer to overflow */ 328 + if (byte_count > CIFSMaxBufSize) 329 + return -ENOBUFS; 324 330 pTargetSMB->smb_buf_length = byte_count; 331 + 332 + memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); 325 333 326 334 if (remaining == total_in_buf2) { 327 335 cFYI(1, "found the last secondary response"); ··· 617 607 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 618 608 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 619 609 620 - if ((mid_entry->mid == smb_buffer->Mid) && 621 - (mid_entry->midState == MID_REQUEST_SUBMITTED) && 622 - (mid_entry->command == smb_buffer->Command)) { 623 - if (length == 0 && 624 - check2ndT2(smb_buffer, server->maxBuf) > 0) { 625 - /* We have a multipart transact2 resp */ 626 - isMultiRsp = true; 627 - if (mid_entry->resp_buf) { 628 - /* merge response - fix up 1st*/ 629 - if (coalesce_t2(smb_buffer, 630 - mid_entry->resp_buf)) { 631 - mid_entry->multiRsp = 632 - true; 633 - break; 634 - } else { 635 - /* all parts received */ 636 - mid_entry->multiEnd = 637 - true; 638 - goto multi_t2_fnd; 639 - } 610 + if (mid_entry->mid != smb_buffer->Mid || 611 + mid_entry->midState != MID_REQUEST_SUBMITTED || 612 + mid_entry->command != smb_buffer->Command) { 613 + mid_entry = NULL; 614 + continue; 615 + } 616 + 617 + if (length == 0 && 618 + check2ndT2(smb_buffer, server->maxBuf) > 0) { 619 + /* We have a multipart transact2 resp */ 620 + isMultiRsp = true; 621 + if (mid_entry->resp_buf) { 622 + /* merge response - fix up 1st*/ 623 + length = coalesce_t2(smb_buffer, 624 + mid_entry->resp_buf); 625 + if (length > 0) { 626 + length = 0; 627 + mid_entry->multiRsp = true; 628 + break; 640 629 } else { 641 - if (!isLargeBuf) { 642 - cERROR(1, "1st trans2 resp needs bigbuf"); 643 - /* BB maybe we can fix this up, switch 644 - to already allocated large buffer? */ 645 - } else { 646 - /* Have first buffer */ 647 - mid_entry->resp_buf = 648 - smb_buffer; 649 - mid_entry->largeBuf = 650 - true; 651 - bigbuf = NULL; 652 - } 630 + /* all parts received or 631 + * packet is malformed 632 + */ 633 + mid_entry->multiEnd = true; 634 + goto multi_t2_fnd; 653 635 } 654 - break; 636 + } else { 637 + if (!isLargeBuf) { 638 + /* 639 + * FIXME: switch to already 640 + * allocated largebuf? 641 + */ 642 + cERROR(1, "1st trans2 resp " 643 + "needs bigbuf"); 644 + } else { 645 + /* Have first buffer */ 646 + mid_entry->resp_buf = 647 + smb_buffer; 648 + mid_entry->largeBuf = true; 649 + bigbuf = NULL; 650 + } 655 651 } 656 - mid_entry->resp_buf = smb_buffer; 657 - mid_entry->largeBuf = isLargeBuf; 658 - multi_t2_fnd: 659 - if (length == 0) 660 - mid_entry->midState = 661 - MID_RESPONSE_RECEIVED; 662 - else 663 - mid_entry->midState = 664 - MID_RESPONSE_MALFORMED; 665 - #ifdef CONFIG_CIFS_STATS2 666 - mid_entry->when_received = jiffies; 667 - #endif 668 - list_del_init(&mid_entry->qhead); 669 - mid_entry->callback(mid_entry); 670 652 break; 671 653 } 672 - mid_entry = NULL; 654 + mid_entry->resp_buf = smb_buffer; 655 + mid_entry->largeBuf = isLargeBuf; 656 + multi_t2_fnd: 657 + if (length == 0) 658 + mid_entry->midState = MID_RESPONSE_RECEIVED; 659 + else 660 + mid_entry->midState = MID_RESPONSE_MALFORMED; 661 + #ifdef CONFIG_CIFS_STATS2 662 + mid_entry->when_received = jiffies; 663 + #endif 664 + list_del_init(&mid_entry->qhead); 665 + mid_entry->callback(mid_entry); 666 + break; 673 667 } 674 668 spin_unlock(&GlobalMid_Lock); 675 669
+4 -15
fs/cifs/sess.c
··· 276 276 } 277 277 278 278 static void 279 - decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses, 279 + decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, 280 280 const struct nls_table *nls_cp) 281 281 { 282 282 int len; 283 283 char *data = *pbcc_area; 284 284 285 285 cFYI(1, "bleft %d", bleft); 286 - 287 - /* 288 - * Windows servers do not always double null terminate their final 289 - * Unicode string. Check to see if there are an uneven number of bytes 290 - * left. If so, then add an extra NULL pad byte to the end of the 291 - * response. 292 - * 293 - * See section 2.7.2 in "Implementing CIFS" for details 294 - */ 295 - if (bleft % 2) { 296 - data[bleft] = 0; 297 - ++bleft; 298 - } 299 286 300 287 kfree(ses->serverOS); 301 288 ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); ··· 916 929 } 917 930 918 931 /* BB check if Unicode and decode strings */ 919 - if (smb_buf->Flags2 & SMBFLG2_UNICODE) { 932 + if (bytes_remaining == 0) { 933 + /* no string area to decode, do nothing */ 934 + } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) { 920 935 /* unicode string area must be word-aligned */ 921 936 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { 922 937 ++bcc_ptr;