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

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: fix length checks in checkSMB
[CIFS] Update cifs minor version
cifs: No need to check crypto blockcipher allocation
cifs: clean up some compiler warnings
cifs: make CIFS depend on CRYPTO_MD4
cifs: force a reconnect if there are too many MIDs in flight
cifs: don't pop a printk when sending on a socket is interrupted
cifs: simplify SMB header check routine
cifs: send an NT_CANCEL request when a process is signalled
cifs: handle cancelled requests better
cifs: fix two compiler warning about uninitialized vars

+130 -85
+1
fs/cifs/Kconfig
··· 3 3 depends on INET 4 4 select NLS 5 5 select CRYPTO 6 + select CRYPTO_MD4 6 7 select CRYPTO_MD5 7 8 select CRYPTO_HMAC 8 9 select CRYPTO_ARC4
+4 -5
fs/cifs/cifs_dfs_ref.c
··· 282 282 cFYI(1, "in %s", __func__); 283 283 BUG_ON(IS_ROOT(mntpt)); 284 284 285 - xid = GetXid(); 286 - 287 285 /* 288 286 * The MSDFS spec states that paths in DFS referral requests and 289 287 * responses must be prefixed by a single '\' character instead of ··· 291 293 mnt = ERR_PTR(-ENOMEM); 292 294 full_path = build_path_from_dentry(mntpt); 293 295 if (full_path == NULL) 294 - goto free_xid; 296 + goto cdda_exit; 295 297 296 298 cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); 297 299 tlink = cifs_sb_tlink(cifs_sb); ··· 301 303 } 302 304 ses = tlink_tcon(tlink)->ses; 303 305 306 + xid = GetXid(); 304 307 rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, 305 308 &num_referrals, &referrals, 306 309 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 310 + FreeXid(xid); 307 311 308 312 cifs_put_tlink(tlink); 309 313 ··· 338 338 free_dfs_info_array(referrals, num_referrals); 339 339 free_full_path: 340 340 kfree(full_path); 341 - free_xid: 342 - FreeXid(xid); 341 + cdda_exit: 343 342 cFYI(1, "leaving %s" , __func__); 344 343 return mnt; 345 344 }
+3 -2
fs/cifs/cifsencrypt.c
··· 657 657 get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); 658 658 659 659 tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 660 - if (!tfm_arc4 || IS_ERR(tfm_arc4)) { 660 + if (IS_ERR(tfm_arc4)) { 661 + rc = PTR_ERR(tfm_arc4); 661 662 cERROR(1, "could not allocate crypto API arc4\n"); 662 - return PTR_ERR(tfm_arc4); 663 + return rc; 663 664 } 664 665 665 666 desc.tfm = tfm_arc4;
+1 -1
fs/cifs/cifsfs.h
··· 127 127 extern const struct export_operations cifs_export_ops; 128 128 #endif /* EXPERIMENTAL */ 129 129 130 - #define CIFS_VERSION "1.69" 130 + #define CIFS_VERSION "1.70" 131 131 #endif /* _CIFSFS_H */
-3
fs/cifs/cifssmb.c
··· 4914 4914 __u16 fid, __u32 pid_of_opener, bool SetAllocation) 4915 4915 { 4916 4916 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4917 - char *data_offset; 4918 4917 struct file_end_of_file_info *parm_data; 4919 4918 int rc = 0; 4920 4919 __u16 params, param_offset, offset, byte_count, count; ··· 4936 4937 pSMB->Reserved2 = 0; 4937 4938 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 4938 4939 offset = param_offset + params; 4939 - 4940 - data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4941 4940 4942 4941 count = sizeof(struct file_end_of_file_info); 4943 4942 pSMB->MaxParameterCount = cpu_to_le16(2);
+2 -6
fs/cifs/file.c
··· 346 346 struct cifsTconInfo *tcon; 347 347 struct tcon_link *tlink; 348 348 struct cifsFileInfo *pCifsFile = NULL; 349 - struct cifsInodeInfo *pCifsInode; 350 349 char *full_path = NULL; 351 350 bool posix_open_ok = false; 352 351 __u16 netfid; ··· 359 360 return PTR_ERR(tlink); 360 361 } 361 362 tcon = tlink_tcon(tlink); 362 - 363 - pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 364 363 365 364 full_path = build_path_from_dentry(file->f_path.dentry); 366 365 if (full_path == NULL) { ··· 1143 1146 char *write_data; 1144 1147 int rc = -EFAULT; 1145 1148 int bytes_written = 0; 1146 - struct cifs_sb_info *cifs_sb; 1147 1149 struct inode *inode; 1148 1150 struct cifsFileInfo *open_file; 1149 1151 ··· 1150 1154 return -EFAULT; 1151 1155 1152 1156 inode = page->mapping->host; 1153 - cifs_sb = CIFS_SB(inode->i_sb); 1154 1157 1155 1158 offset += (loff_t)from; 1156 1159 write_data = kmap(page); ··· 1662 1667 cifs_iovec_write(struct file *file, const struct iovec *iov, 1663 1668 unsigned long nr_segs, loff_t *poffset) 1664 1669 { 1665 - size_t total_written = 0, written = 0; 1670 + size_t total_written = 0; 1671 + unsigned int written = 0; 1666 1672 unsigned long num_pages, npages; 1667 1673 size_t copied, len, cur_len, i; 1668 1674 struct kvec *to_send;
+2 -1
fs/cifs/link.c
··· 55 55 56 56 md5 = crypto_alloc_shash("md5", 0, 0); 57 57 if (IS_ERR(md5)) { 58 + rc = PTR_ERR(md5); 58 59 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); 59 - return PTR_ERR(md5); 60 + return rc; 60 61 } 61 62 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); 62 63 sdescmd5 = kmalloc(size, GFP_KERNEL);
+65 -51
fs/cifs/misc.c
··· 236 236 { 237 237 __u16 mid = 0; 238 238 __u16 last_mid; 239 - int collision; 240 - 241 - if (server == NULL) 242 - return mid; 239 + bool collision; 243 240 244 241 spin_lock(&GlobalMid_Lock); 245 242 last_mid = server->CurrentMid; /* we do not want to loop forever */ ··· 249 252 (and it would also have to have been a request that 250 253 did not time out) */ 251 254 while (server->CurrentMid != last_mid) { 252 - struct list_head *tmp; 253 255 struct mid_q_entry *mid_entry; 256 + unsigned int num_mids; 254 257 255 - collision = 0; 258 + collision = false; 256 259 if (server->CurrentMid == 0) 257 260 server->CurrentMid++; 258 261 259 - list_for_each(tmp, &server->pending_mid_q) { 260 - mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 261 - 262 - if ((mid_entry->mid == server->CurrentMid) && 263 - (mid_entry->midState == MID_REQUEST_SUBMITTED)) { 262 + num_mids = 0; 263 + list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 264 + ++num_mids; 265 + if (mid_entry->mid == server->CurrentMid && 266 + mid_entry->midState == MID_REQUEST_SUBMITTED) { 264 267 /* This mid is in use, try a different one */ 265 - collision = 1; 268 + collision = true; 266 269 break; 267 270 } 268 271 } 269 - if (collision == 0) { 272 + 273 + /* 274 + * if we have more than 32k mids in the list, then something 275 + * is very wrong. Possibly a local user is trying to DoS the 276 + * box by issuing long-running calls and SIGKILL'ing them. If 277 + * we get to 2^16 mids then we're in big trouble as this 278 + * function could loop forever. 279 + * 280 + * Go ahead and assign out the mid in this situation, but force 281 + * an eventual reconnect to clean out the pending_mid_q. 282 + */ 283 + if (num_mids > 32768) 284 + server->tcpStatus = CifsNeedReconnect; 285 + 286 + if (!collision) { 270 287 mid = server->CurrentMid; 271 288 break; 272 289 } ··· 392 381 } 393 382 394 383 static int 395 - checkSMBhdr(struct smb_hdr *smb, __u16 mid) 384 + check_smb_hdr(struct smb_hdr *smb, __u16 mid) 396 385 { 397 - /* Make sure that this really is an SMB, that it is a response, 398 - and that the message ids match */ 399 - if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && 400 - (mid == smb->Mid)) { 401 - if (smb->Flags & SMBFLG_RESPONSE) 402 - return 0; 403 - else { 404 - /* only one valid case where server sends us request */ 405 - if (smb->Command == SMB_COM_LOCKING_ANDX) 406 - return 0; 407 - else 408 - cERROR(1, "Received Request not response"); 409 - } 410 - } else { /* bad signature or mid */ 411 - if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) 412 - cERROR(1, "Bad protocol string signature header %x", 413 - *(unsigned int *) smb->Protocol); 414 - if (mid != smb->Mid) 415 - cERROR(1, "Mids do not match"); 386 + /* does it have the right SMB "signature" ? */ 387 + if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) { 388 + cERROR(1, "Bad protocol string signature header 0x%x", 389 + *(unsigned int *)smb->Protocol); 390 + return 1; 416 391 } 417 - cERROR(1, "bad smb detected. The Mid=%d", smb->Mid); 392 + 393 + /* Make sure that message ids match */ 394 + if (mid != smb->Mid) { 395 + cERROR(1, "Mids do not match. received=%u expected=%u", 396 + smb->Mid, mid); 397 + return 1; 398 + } 399 + 400 + /* if it's a response then accept */ 401 + if (smb->Flags & SMBFLG_RESPONSE) 402 + return 0; 403 + 404 + /* only one valid case where server sends us request */ 405 + if (smb->Command == SMB_COM_LOCKING_ANDX) 406 + return 0; 407 + 408 + cERROR(1, "Server sent request, not response. mid=%u", smb->Mid); 418 409 return 1; 419 410 } 420 411 ··· 461 448 return 1; 462 449 } 463 450 464 - if (checkSMBhdr(smb, mid)) 451 + if (check_smb_hdr(smb, mid)) 465 452 return 1; 466 453 clc_len = smbCalcSize_LE(smb); 467 454 ··· 478 465 if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) 479 466 return 0; /* bcc wrapped */ 480 467 } 481 - cFYI(1, "Calculated size %d vs length %d mismatch for mid %d", 468 + cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u", 482 469 clc_len, 4 + len, smb->Mid); 483 - /* Windows XP can return a few bytes too much, presumably 484 - an illegal pad, at the end of byte range lock responses 485 - so we allow for that three byte pad, as long as actual 486 - received length is as long or longer than calculated length */ 487 - /* We have now had to extend this more, since there is a 488 - case in which it needs to be bigger still to handle a 489 - malformed response to transact2 findfirst from WinXP when 490 - access denied is returned and thus bcc and wct are zero 491 - but server says length is 0x21 bytes too long as if the server 492 - forget to reset the smb rfc1001 length when it reset the 493 - wct and bcc to minimum size and drop the t2 parms and data */ 494 - if ((4+len > clc_len) && (len <= clc_len + 512)) 495 - return 0; 496 - else { 497 - cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d", 470 + 471 + if (4 + len < clc_len) { 472 + cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u", 498 473 len, smb->Mid); 474 + return 1; 475 + } else if (len > clc_len + 512) { 476 + /* 477 + * Some servers (Windows XP in particular) send more 478 + * data than the lengths in the SMB packet would 479 + * indicate on certain calls (byte range locks and 480 + * trans2 find first calls in particular). While the 481 + * client can handle such a frame by ignoring the 482 + * trailing data, we choose limit the amount of extra 483 + * data to 512 bytes. 484 + */ 485 + cERROR(1, "RFC1001 size %u more than 512 bytes larger " 486 + "than SMB for mid=%u", len, smb->Mid); 499 487 return 1; 500 488 } 501 489 }
-3
fs/cifs/readdir.c
··· 764 764 { 765 765 int rc = 0; 766 766 int xid, i; 767 - struct cifs_sb_info *cifs_sb; 768 767 struct cifsTconInfo *pTcon; 769 768 struct cifsFileInfo *cifsFile = NULL; 770 769 char *current_entry; ··· 773 774 unsigned int max_len; 774 775 775 776 xid = GetXid(); 776 - 777 - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 778 777 779 778 /* 780 779 * Ensure FindFirst doesn't fail before doing filldir() for '.' and
+2 -1
fs/cifs/smbencrypt.c
··· 58 58 59 59 md4 = crypto_alloc_shash("md4", 0, 0); 60 60 if (IS_ERR(md4)) { 61 + rc = PTR_ERR(md4); 61 62 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); 62 - return PTR_ERR(md4); 63 + return rc; 63 64 } 64 65 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); 65 66 sdescmd4 = kmalloc(size, GFP_KERNEL);
+50 -12
fs/cifs/transport.c
··· 236 236 server->tcpStatus = CifsNeedReconnect; 237 237 } 238 238 239 - if (rc < 0) { 239 + if (rc < 0 && rc != -EINTR) 240 240 cERROR(1, "Error %d sending data on socket to server", rc); 241 - } else 241 + else 242 242 rc = 0; 243 243 244 244 /* Don't want to modify the buffer as a ··· 570 570 #endif 571 571 572 572 mutex_unlock(&ses->server->srv_mutex); 573 - cifs_small_buf_release(in_buf); 574 573 575 - if (rc < 0) 574 + if (rc < 0) { 575 + cifs_small_buf_release(in_buf); 576 576 goto out; 577 + } 577 578 578 - if (long_op == CIFS_ASYNC_OP) 579 + if (long_op == CIFS_ASYNC_OP) { 580 + cifs_small_buf_release(in_buf); 579 581 goto out; 582 + } 580 583 581 584 rc = wait_for_response(ses->server, midQ); 582 - if (rc != 0) 583 - goto out; 585 + if (rc != 0) { 586 + send_nt_cancel(ses->server, in_buf, midQ); 587 + spin_lock(&GlobalMid_Lock); 588 + if (midQ->midState == MID_REQUEST_SUBMITTED) { 589 + midQ->callback = DeleteMidQEntry; 590 + spin_unlock(&GlobalMid_Lock); 591 + cifs_small_buf_release(in_buf); 592 + atomic_dec(&ses->server->inFlight); 593 + wake_up(&ses->server->request_q); 594 + return rc; 595 + } 596 + spin_unlock(&GlobalMid_Lock); 597 + } 598 + 599 + cifs_small_buf_release(in_buf); 584 600 585 601 rc = sync_mid_result(midQ, ses->server); 586 602 if (rc != 0) { ··· 740 724 goto out; 741 725 742 726 rc = wait_for_response(ses->server, midQ); 743 - if (rc != 0) 744 - goto out; 727 + if (rc != 0) { 728 + send_nt_cancel(ses->server, in_buf, midQ); 729 + spin_lock(&GlobalMid_Lock); 730 + if (midQ->midState == MID_REQUEST_SUBMITTED) { 731 + /* no longer considered to be "in-flight" */ 732 + midQ->callback = DeleteMidQEntry; 733 + spin_unlock(&GlobalMid_Lock); 734 + atomic_dec(&ses->server->inFlight); 735 + wake_up(&ses->server->request_q); 736 + return rc; 737 + } 738 + spin_unlock(&GlobalMid_Lock); 739 + } 745 740 746 741 rc = sync_mid_result(midQ, ses->server); 747 742 if (rc != 0) { ··· 949 922 } 950 923 } 951 924 952 - if (wait_for_response(ses->server, midQ) == 0) { 953 - /* We got the response - restart system call. */ 954 - rstart = 1; 925 + rc = wait_for_response(ses->server, midQ); 926 + if (rc) { 927 + send_nt_cancel(ses->server, in_buf, midQ); 928 + spin_lock(&GlobalMid_Lock); 929 + if (midQ->midState == MID_REQUEST_SUBMITTED) { 930 + /* no longer considered to be "in-flight" */ 931 + midQ->callback = DeleteMidQEntry; 932 + spin_unlock(&GlobalMid_Lock); 933 + return rc; 934 + } 935 + spin_unlock(&GlobalMid_Lock); 955 936 } 937 + 938 + /* We got the response - restart system call. */ 939 + rstart = 1; 956 940 } 957 941 958 942 rc = sync_mid_result(midQ, ses->server);