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 tag '4.17-rc1SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"SMB3 fixes, a few for stable, and some important cleanup work from
Ronnie of the smb3 transport code"

* tag '4.17-rc1SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: change validate_buf to validate_iov
cifs: remove rfc1002 hardcoded constants from cifs_discard_remaining_data()
cifs: Change SMB2_open to return an iov for the error parameter
cifs: add resp_buf_size to the mid_q_entry structure
smb3.11: replace a 4 with server->vals->header_preamble_size
cifs: replace a 4 with server->vals->header_preamble_size
cifs: add pdu_size to the TCP_Server_Info structure
SMB311: Improve checking of negotiate security contexts
SMB3: Fix length checking of SMB3.11 negotiate request
CIFS: add ONCE flag for cifs_dbg type
cifs: Use ULL suffix for 64-bit constant
SMB3: Log at least once if tree connect fails during reconnect
cifs: smb2pdu: Fix potential NULL pointer dereference

+240 -71
-17
fs/cifs/cifs_debug.c
··· 42 42 data, length, true); 43 43 } 44 44 45 - #ifdef CONFIG_CIFS_DEBUG 46 - void cifs_vfs_err(const char *fmt, ...) 47 - { 48 - struct va_format vaf; 49 - va_list args; 50 - 51 - va_start(args, fmt); 52 - 53 - vaf.fmt = fmt; 54 - vaf.va = &args; 55 - 56 - pr_err_ratelimited("CIFS VFS: %pV", &vaf); 57 - 58 - va_end(args); 59 - } 60 - #endif 61 - 62 45 void cifs_dump_detail(void *buf) 63 46 { 64 47 #ifdef CONFIG_CIFS_DEBUG2
+22 -12
fs/cifs/cifs_debug.h
··· 39 39 #else 40 40 #define NOISY 0 41 41 #endif 42 + #define ONCE 8 42 43 43 44 /* 44 45 * debug ON ··· 47 46 */ 48 47 #ifdef CONFIG_CIFS_DEBUG 49 48 50 - __printf(1, 2) void cifs_vfs_err(const char *fmt, ...); 51 - 52 49 /* information message: e.g., configuration, major event */ 53 - #define cifs_dbg(type, fmt, ...) \ 54 - do { \ 55 - if (type == FYI && cifsFYI & CIFS_INFO) { \ 56 - pr_debug_ratelimited("%s: " \ 57 - fmt, __FILE__, ##__VA_ARGS__); \ 58 - } else if (type == VFS) { \ 59 - cifs_vfs_err(fmt, ##__VA_ARGS__); \ 60 - } else if (type == NOISY && type != 0) { \ 61 - pr_debug_ratelimited(fmt, ##__VA_ARGS__); \ 62 - } \ 50 + #define cifs_dbg_func(ratefunc, type, fmt, ...) \ 51 + do { \ 52 + if ((type) & FYI && cifsFYI & CIFS_INFO) { \ 53 + pr_debug_ ## ratefunc("%s: " \ 54 + fmt, __FILE__, ##__VA_ARGS__); \ 55 + } else if ((type) & VFS) { \ 56 + pr_err_ ## ratefunc("CuIFS VFS: " \ 57 + fmt, ##__VA_ARGS__); \ 58 + } else if ((type) & NOISY && (NOISY != 0)) { \ 59 + pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \ 60 + } \ 61 + } while (0) 62 + 63 + #define cifs_dbg(type, fmt, ...) \ 64 + do { \ 65 + if ((type) & ONCE) \ 66 + cifs_dbg_func(once, \ 67 + type, fmt, ##__VA_ARGS__); \ 68 + else \ 69 + cifs_dbg_func(ratelimited, \ 70 + type, fmt, ##__VA_ARGS__); \ 63 71 } while (0) 64 72 65 73 /*
+4
fs/cifs/cifsglob.h
··· 665 665 struct delayed_work echo; /* echo ping workqueue job */ 666 666 char *smallbuf; /* pointer to current "small" buffer */ 667 667 char *bigbuf; /* pointer to current "big" buffer */ 668 + /* Total size of this PDU. Only valid from cifs_demultiplex_thread */ 669 + unsigned int pdu_size; 668 670 unsigned int total_read; /* total amount of data read in this pass */ 669 671 #ifdef CONFIG_CIFS_FSCACHE 670 672 struct fscache_cookie *fscache; /* client index cache cookie */ ··· 678 676 unsigned int max_read; 679 677 unsigned int max_write; 680 678 #ifdef CONFIG_CIFS_SMB311 679 + __le16 cipher_type; 681 680 /* save initital negprot hash */ 682 681 __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; 683 682 #endif /* 3.1.1 */ ··· 1376 1373 mid_handle_t *handle; /* call handle mid callback */ 1377 1374 void *callback_data; /* general purpose pointer for callback */ 1378 1375 void *resp_buf; /* pointer to received SMB header */ 1376 + unsigned int resp_buf_size; 1379 1377 int mid_state; /* wish this were enum but can not pass to wait_event */ 1380 1378 unsigned int mid_flags; 1381 1379 __le16 command; /* smb command code */
+7 -4
fs/cifs/cifssmb.c
··· 206 206 mutex_unlock(&ses->session_mutex); 207 207 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); 208 208 209 - if (rc) 209 + if (rc) { 210 + printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc); 210 211 goto out; 212 + } 211 213 212 214 atomic_inc(&tconInfoReconnectCount); 213 215 ··· 1418 1416 int 1419 1417 cifs_discard_remaining_data(struct TCP_Server_Info *server) 1420 1418 { 1421 - unsigned int rfclen = get_rfc1002_length(server->smallbuf); 1422 - int remaining = rfclen + 4 - server->total_read; 1419 + unsigned int rfclen = server->pdu_size; 1420 + int remaining = rfclen + server->vals->header_preamble_size - 1421 + server->total_read; 1423 1422 1424 1423 while (remaining > 0) { 1425 1424 int length; ··· 1457 1454 unsigned int data_offset, data_len; 1458 1455 struct cifs_readdata *rdata = mid->callback_data; 1459 1456 char *buf = server->smallbuf; 1460 - unsigned int buflen = get_rfc1002_length(buf) + 1457 + unsigned int buflen = server->pdu_size + 1461 1458 server->vals->header_preamble_size; 1462 1459 bool use_rdma_mr = false; 1463 1460
+3 -1
fs/cifs/connect.c
··· 772 772 { 773 773 int length; 774 774 char *buf = server->smallbuf; 775 - unsigned int pdu_length = get_rfc1002_length(buf); 775 + unsigned int pdu_length = server->pdu_size; 776 776 777 777 /* make sure this will fit in a large buffer */ 778 778 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - ··· 881 881 * so we can now interpret the length field. 882 882 */ 883 883 pdu_length = get_rfc1002_length(buf); 884 + server->pdu_size = pdu_length; 884 885 885 886 cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length); 886 887 if (!is_smb_response(server, buf[0])) ··· 928 927 929 928 server->lstrp = jiffies; 930 929 if (mid_entry != NULL) { 930 + mid_entry->resp_buf_size = server->pdu_size; 931 931 if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && 932 932 mid_entry->mid_state == MID_RESPONSE_RECEIVED && 933 933 server->ops->handle_cancelled_mid)
+1 -1
fs/cifs/inode.c
··· 710 710 /* Simple function to return a 64 bit hash of string. Rarely called */ 711 711 static __u64 simple_hashstr(const char *str) 712 712 { 713 - const __u64 hash_mult = 1125899906842597L; /* a big enough prime */ 713 + const __u64 hash_mult = 1125899906842597ULL; /* a big enough prime */ 714 714 __u64 hash = 0; 715 715 716 716 while (*str)
+42
fs/cifs/smb2misc.c
··· 93 93 /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24) 94 94 }; 95 95 96 + #ifdef CONFIG_CIFS_SMB311 97 + static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len, __u32 non_ctxlen, 98 + size_t hdr_preamble_size) 99 + { 100 + __u16 neg_count; 101 + __u32 nc_offset, size_of_pad_before_neg_ctxts; 102 + struct smb2_negotiate_rsp *pneg_rsp = (struct smb2_negotiate_rsp *)hdr; 103 + 104 + /* Negotiate contexts are only valid for latest dialect SMB3.11 */ 105 + neg_count = le16_to_cpu(pneg_rsp->NegotiateContextCount); 106 + if ((neg_count == 0) || 107 + (pneg_rsp->DialectRevision != cpu_to_le16(SMB311_PROT_ID))) 108 + return 0; 109 + 110 + /* Make sure that negotiate contexts start after gss security blob */ 111 + nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset); 112 + if (nc_offset < non_ctxlen - hdr_preamble_size /* RFC1001 len */) { 113 + printk_once(KERN_WARNING "invalid negotiate context offset\n"); 114 + return 0; 115 + } 116 + size_of_pad_before_neg_ctxts = nc_offset - 117 + (non_ctxlen - hdr_preamble_size); 118 + 119 + /* Verify that at least minimal negotiate contexts fit within frame */ 120 + if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) { 121 + printk_once(KERN_WARNING "negotiate context goes beyond end\n"); 122 + return 0; 123 + } 124 + 125 + cifs_dbg(FYI, "length of negcontexts %d pad %d\n", 126 + len - nc_offset, size_of_pad_before_neg_ctxts); 127 + 128 + /* length of negcontexts including pad from end of sec blob to them */ 129 + return (len - nc_offset) + size_of_pad_before_neg_ctxts; 130 + } 131 + #endif /* CIFS_SMB311 */ 132 + 96 133 int 97 134 smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) 98 135 { ··· 235 198 236 199 clc_len = smb2_calc_size(hdr); 237 200 201 + #ifdef CONFIG_CIFS_SMB311 202 + if (shdr->Command == SMB2_NEGOTIATE) 203 + clc_len += get_neg_ctxt_len(hdr, len, clc_len, 204 + srvr->vals->header_preamble_size); 205 + #endif /* SMB311 */ 238 206 if (srvr->vals->header_preamble_size + len != clc_len) { 239 207 cifs_dbg(FYI, "Calculated size %u length %zu mismatch mid %llu\n", 240 208 clc_len, srvr->vals->header_preamble_size + len, mid);
+10 -8
fs/cifs/smb2ops.c
··· 1451 1451 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 1452 1452 struct cifs_open_parms oparms; 1453 1453 struct cifs_fid fid; 1454 + struct kvec err_iov = {NULL, 0}; 1454 1455 struct smb2_err_rsp *err_buf = NULL; 1455 1456 struct smb2_symlink_err_rsp *symlink; 1456 1457 unsigned int sub_len; ··· 1474 1473 oparms.fid = &fid; 1475 1474 oparms.reconnect = false; 1476 1475 1477 - rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf); 1476 + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_iov); 1478 1477 1479 1478 if (!rc || !err_buf) { 1480 1479 kfree(utf16_path); 1481 1480 return -ENOENT; 1482 1481 } 1483 1482 1483 + err_buf = err_iov.iov_base; 1484 1484 if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || 1485 - get_rfc1002_length(err_buf) + server->vals->header_preamble_size < SMB2_SYMLINK_STRUCT_SIZE) { 1485 + err_iov.iov_len + server->vals->header_preamble_size < SMB2_SYMLINK_STRUCT_SIZE) { 1486 1486 kfree(utf16_path); 1487 1487 return -ENOENT; 1488 1488 } ··· 1496 1494 print_len = le16_to_cpu(symlink->PrintNameLength); 1497 1495 print_offset = le16_to_cpu(symlink->PrintNameOffset); 1498 1496 1499 - if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size < 1497 + if (err_iov.iov_len + server->vals->header_preamble_size < 1500 1498 SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { 1501 1499 kfree(utf16_path); 1502 1500 return -ENOENT; 1503 1501 } 1504 1502 1505 - if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size < 1503 + if (err_iov.iov_len + server->vals->header_preamble_size < 1506 1504 SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { 1507 1505 kfree(utf16_path); 1508 1506 return -ENOENT; ··· 2552 2550 unsigned int npages; 2553 2551 struct page **pages; 2554 2552 unsigned int len; 2555 - unsigned int buflen = get_rfc1002_length(buf) + server->vals->header_preamble_size; 2553 + unsigned int buflen = server->pdu_size + server->vals->header_preamble_size; 2556 2554 int rc; 2557 2555 int i = 0; 2558 2556 ··· 2626 2624 { 2627 2625 int length; 2628 2626 char *buf = server->smallbuf; 2629 - unsigned int pdu_length = get_rfc1002_length(buf); 2627 + unsigned int pdu_length = server->pdu_size; 2630 2628 unsigned int buf_size; 2631 2629 struct mid_q_entry *mid_entry; 2632 2630 ··· 2670 2668 smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid) 2671 2669 { 2672 2670 char *buf = server->smallbuf; 2673 - unsigned int pdu_length = get_rfc1002_length(buf); 2671 + unsigned int pdu_length = server->pdu_size; 2674 2672 struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; 2675 2673 unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize); 2676 2674 ··· 2701 2699 { 2702 2700 char *buf = server->large_buf ? server->bigbuf : server->smallbuf; 2703 2701 2704 - return handle_read_data(server, mid, buf, get_rfc1002_length(buf) + 2702 + return handle_read_data(server, mid, buf, server->pdu_size + 2705 2703 server->vals->header_preamble_size, 2706 2704 NULL, 0, 0); 2707 2705 }
+138 -25
fs/cifs/smb2pdu.c
··· 268 268 mutex_unlock(&tcon->ses->session_mutex); 269 269 270 270 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); 271 - if (rc) 271 + if (rc) { 272 + /* If sess reconnected but tcon didn't, something strange ... */ 273 + printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc); 272 274 goto out; 275 + } 273 276 274 277 if (smb2_command != SMB2_INTERNAL_CMD) 275 278 queue_delayed_work(cifsiod_wq, &server->reconnect, 0); ··· 406 403 *total_len += 4 + sizeof(struct smb2_preauth_neg_context) 407 404 + sizeof(struct smb2_encryption_neg_context); 408 405 } 406 + 407 + static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) 408 + { 409 + unsigned int len = le16_to_cpu(ctxt->DataLength); 410 + 411 + /* If invalid preauth context warn but use what we requested, SHA-512 */ 412 + if (len < MIN_PREAUTH_CTXT_DATA_LEN) { 413 + printk_once(KERN_WARNING "server sent bad preauth context\n"); 414 + return; 415 + } 416 + if (le16_to_cpu(ctxt->HashAlgorithmCount) != 1) 417 + printk_once(KERN_WARNING "illegal SMB3 hash algorithm count\n"); 418 + if (ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512) 419 + printk_once(KERN_WARNING "unknown SMB3 hash algorithm\n"); 420 + } 421 + 422 + static int decode_encrypt_ctx(struct TCP_Server_Info *server, 423 + struct smb2_encryption_neg_context *ctxt) 424 + { 425 + unsigned int len = le16_to_cpu(ctxt->DataLength); 426 + 427 + cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len); 428 + if (len < MIN_ENCRYPT_CTXT_DATA_LEN) { 429 + printk_once(KERN_WARNING "server sent bad crypto ctxt len\n"); 430 + return -EINVAL; 431 + } 432 + 433 + if (le16_to_cpu(ctxt->CipherCount) != 1) { 434 + printk_once(KERN_WARNING "illegal SMB3.11 cipher count\n"); 435 + return -EINVAL; 436 + } 437 + cifs_dbg(FYI, "SMB311 cipher type:%d\n", le16_to_cpu(ctxt->Ciphers[0])); 438 + if ((ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_CCM) && 439 + (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_GCM)) { 440 + printk_once(KERN_WARNING "invalid SMB3.11 cipher returned\n"); 441 + return -EINVAL; 442 + } 443 + server->cipher_type = ctxt->Ciphers[0]; 444 + return 0; 445 + } 446 + 447 + static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, 448 + struct TCP_Server_Info *server) 449 + { 450 + struct smb2_neg_context *pctx; 451 + unsigned int offset = le32_to_cpu(rsp->NegotiateContextOffset); 452 + unsigned int ctxt_cnt = le16_to_cpu(rsp->NegotiateContextCount); 453 + unsigned int len_of_smb = be32_to_cpu(rsp->hdr.smb2_buf_length); 454 + unsigned int len_of_ctxts, i; 455 + int rc = 0; 456 + 457 + cifs_dbg(FYI, "decoding %d negotiate contexts\n", ctxt_cnt); 458 + if (len_of_smb <= offset) { 459 + cifs_dbg(VFS, "Invalid response: negotiate context offset\n"); 460 + return -EINVAL; 461 + } 462 + 463 + len_of_ctxts = len_of_smb - offset; 464 + 465 + for (i = 0; i < ctxt_cnt; i++) { 466 + int clen; 467 + /* check that offset is not beyond end of SMB */ 468 + if (len_of_ctxts == 0) 469 + break; 470 + 471 + if (len_of_ctxts < sizeof(struct smb2_neg_context)) 472 + break; 473 + 474 + pctx = (struct smb2_neg_context *)(offset + 475 + server->vals->header_preamble_size + (char *)rsp); 476 + clen = le16_to_cpu(pctx->DataLength); 477 + if (clen > len_of_ctxts) 478 + break; 479 + 480 + if (pctx->ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) 481 + decode_preauth_context( 482 + (struct smb2_preauth_neg_context *)pctx); 483 + else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) 484 + rc = decode_encrypt_ctx(server, 485 + (struct smb2_encryption_neg_context *)pctx); 486 + else 487 + cifs_dbg(VFS, "unknown negcontext of type %d ignored\n", 488 + le16_to_cpu(pctx->ContextType)); 489 + 490 + if (rc) 491 + break; 492 + /* offsets must be 8 byte aligned */ 493 + clen = (clen + 7) & ~0x7; 494 + offset += clen + sizeof(struct smb2_neg_context); 495 + len_of_ctxts -= clen; 496 + } 497 + return rc; 498 + } 499 + 409 500 #else 410 501 static void assemble_neg_contexts(struct smb2_negotiate_req *req, 411 502 unsigned int *total_len) ··· 713 616 else if (rc == 0) 714 617 rc = -EIO; 715 618 } 619 + 620 + #ifdef CONFIG_CIFS_SMB311 621 + if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) { 622 + if (rsp->NegotiateContextCount) 623 + rc = smb311_decode_neg_context(rsp, server); 624 + else 625 + cifs_dbg(VFS, "Missing expected negotiate contexts\n"); 626 + } 627 + #endif /* CONFIG_CIFS_SMB311 */ 716 628 neg_exit: 717 629 free_rsp_buf(resp_buftype, rsp); 718 630 return rc; ··· 1132 1026 if (rc) 1133 1027 goto out; 1134 1028 1135 - if (offsetof(struct smb2_sess_setup_rsp, Buffer) - 4 != 1029 + if (offsetof(struct smb2_sess_setup_rsp, Buffer) - ses->server->vals->header_preamble_size != 1136 1030 le16_to_cpu(rsp->SecurityBufferOffset)) { 1137 1031 cifs_dbg(VFS, "Invalid security buffer offset %d\n", 1138 1032 le16_to_cpu(rsp->SecurityBufferOffset)); ··· 1807 1701 int 1808 1702 SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, 1809 1703 __u8 *oplock, struct smb2_file_all_info *buf, 1810 - struct smb2_err_rsp **err_buf) 1704 + struct kvec *err_iov) 1811 1705 { 1812 1706 struct smb2_create_req *req; 1813 1707 struct smb2_create_rsp *rsp; ··· 1947 1841 1948 1842 if (rc != 0) { 1949 1843 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); 1950 - if (err_buf && rsp) 1951 - *err_buf = kmemdup(rsp, get_rfc1002_length(rsp) + 4, 1952 - GFP_KERNEL); 1844 + if (err_iov && rsp) { 1845 + *err_iov = rsp_iov; 1846 + resp_buftype = CIFS_NO_BUFFER; 1847 + rsp = NULL; 1848 + } 1953 1849 goto creat_exit; 1954 1850 } 1955 1851 ··· 2206 2098 } 2207 2099 2208 2100 static int 2209 - validate_buf(unsigned int offset, unsigned int buffer_length, 2210 - struct smb2_hdr *hdr, unsigned int min_buf_size) 2211 - 2101 + validate_iov(struct TCP_Server_Info *server, 2102 + unsigned int offset, unsigned int buffer_length, 2103 + struct kvec *iov, unsigned int min_buf_size) 2212 2104 { 2213 - unsigned int smb_len = be32_to_cpu(hdr->smb2_buf_length); 2214 - char *end_of_smb = smb_len + 4 /* RFC1001 length field */ + (char *)hdr; 2215 - char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr; 2105 + unsigned int smb_len = iov->iov_len; 2106 + char *end_of_smb = smb_len + server->vals->header_preamble_size + (char *)iov->iov_base; 2107 + char *begin_of_buf = server->vals->header_preamble_size + offset + (char *)iov->iov_base; 2216 2108 char *end_of_buf = begin_of_buf + buffer_length; 2217 2109 2218 2110 ··· 2242 2134 * Caller must free buffer. 2243 2135 */ 2244 2136 static int 2245 - validate_and_copy_buf(unsigned int offset, unsigned int buffer_length, 2246 - struct smb2_hdr *hdr, unsigned int minbufsize, 2137 + validate_and_copy_iov(struct TCP_Server_Info *server, 2138 + unsigned int offset, unsigned int buffer_length, 2139 + struct kvec *iov, unsigned int minbufsize, 2247 2140 char *data) 2248 - 2249 2141 { 2250 - char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr; 2142 + char *begin_of_buf = server->vals->header_preamble_size + offset + (char *)(iov->iov_base); 2251 2143 int rc; 2252 2144 2253 2145 if (!data) 2254 2146 return -EINVAL; 2255 2147 2256 - rc = validate_buf(offset, buffer_length, hdr, minbufsize); 2148 + rc = validate_iov(server, offset, buffer_length, iov, minbufsize); 2257 2149 if (rc) 2258 2150 return rc; 2259 2151 ··· 2331 2223 } 2332 2224 } 2333 2225 2334 - rc = validate_and_copy_buf(le16_to_cpu(rsp->OutputBufferOffset), 2226 + rc = validate_and_copy_iov(ses->server, 2227 + le16_to_cpu(rsp->OutputBufferOffset), 2335 2228 le32_to_cpu(rsp->OutputBufferLength), 2336 - &rsp->hdr, min_len, *data); 2229 + &rsp_iov, min_len, *data); 2337 2230 2338 2231 qinf_exit: 2339 2232 free_rsp_buf(resp_buftype, rsp); ··· 3255 3146 goto qdir_exit; 3256 3147 } 3257 3148 3258 - rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset), 3259 - le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr, 3149 + rc = validate_iov(server, 3150 + le16_to_cpu(rsp->OutputBufferOffset), 3151 + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3260 3152 info_buf_size); 3261 3153 if (rc) 3262 3154 goto qdir_exit; ··· 3564 3454 build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, 3565 3455 int outbuf_len, u64 persistent_fid, u64 volatile_fid) 3566 3456 { 3567 - struct TCP_Server_Info *server = tcon->ses->server; 3457 + struct TCP_Server_Info *server; 3568 3458 int rc; 3569 3459 struct smb2_query_info_req *req; 3570 3460 unsigned int total_len; ··· 3573 3463 3574 3464 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) 3575 3465 return -EIO; 3466 + 3467 + server = tcon->ses->server; 3576 3468 3577 3469 rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req, 3578 3470 &total_len); ··· 3629 3517 3630 3518 info = (struct smb2_fs_full_size_info *)(server->vals->header_preamble_size + 3631 3519 le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr); 3632 - rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset), 3633 - le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr, 3520 + rc = validate_iov(server, 3521 + le16_to_cpu(rsp->OutputBufferOffset), 3522 + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3634 3523 sizeof(struct smb2_fs_full_size_info)); 3635 3524 if (!rc) 3636 3525 copy_fs_info_to_kstatfs(info, fsdata); ··· 3687 3574 3688 3575 rsp_len = le32_to_cpu(rsp->OutputBufferLength); 3689 3576 offset = le16_to_cpu(rsp->OutputBufferOffset); 3690 - rc = validate_buf(offset, rsp_len, &rsp->hdr, min_len); 3577 + rc = validate_iov(server, offset, rsp_len, &rsp_iov, min_len); 3691 3578 if (rc) 3692 3579 goto qfsattr_exit; 3693 3580
+10
fs/cifs/smb2pdu.h
··· 263 263 #define SMB2_NT_FIND 0x00100000 264 264 #define SMB2_LARGE_FILES 0x00200000 265 265 266 + struct smb2_neg_context { 267 + __le16 ContextType; 268 + __le16 DataLength; 269 + __le32 Reserved; 270 + /* Followed by array of data */ 271 + } __packed; 272 + 266 273 #define SMB311_SALT_SIZE 32 267 274 /* Hash Algorithm Types */ 268 275 #define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001) 269 276 #define SMB2_PREAUTH_HASH_SIZE 64 270 277 278 + #define MIN_PREAUTH_CTXT_DATA_LEN (SMB311_SALT_SIZE + 6) 271 279 struct smb2_preauth_neg_context { 272 280 __le16 ContextType; /* 1 */ 273 281 __le16 DataLength; ··· 290 282 #define SMB2_ENCRYPTION_AES128_CCM cpu_to_le16(0x0001) 291 283 #define SMB2_ENCRYPTION_AES128_GCM cpu_to_le16(0x0002) 292 284 285 + /* Min encrypt context data is one cipher so 2 bytes + 2 byte count field */ 286 + #define MIN_ENCRYPT_CTXT_DATA_LEN 4 293 287 struct smb2_encryption_neg_context { 294 288 __le16 ContextType; /* 2 */ 295 289 __le16 DataLength;
+1 -1
fs/cifs/smb2proto.h
··· 122 122 extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, 123 123 __le16 *path, __u8 *oplock, 124 124 struct smb2_file_all_info *buf, 125 - struct smb2_err_rsp **err_buf); 125 + struct kvec *err_iov); 126 126 extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, 127 127 u64 persistent_fid, u64 volatile_fid, u32 opcode, 128 128 bool is_fsctl, char *in_data, u32 indatalen,
+1 -1
fs/cifs/smb2transport.c
··· 604 604 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, 605 605 bool log_error) 606 606 { 607 - unsigned int len = get_rfc1002_length(mid->resp_buf); 607 + unsigned int len = mid->resp_buf_size; 608 608 struct kvec iov[2]; 609 609 struct smb_rqst rqst = { .rq_iov = iov, 610 610 .rq_nvec = 2 };
+1 -1
fs/cifs/transport.c
··· 790 790 791 791 buf = (char *)midQ->resp_buf; 792 792 resp_iov->iov_base = buf; 793 - resp_iov->iov_len = get_rfc1002_length(buf) + 793 + resp_iov->iov_len = midQ->resp_buf_size + 794 794 ses->server->vals->header_preamble_size; 795 795 if (midQ->large_buf) 796 796 *resp_buf_type = CIFS_LARGE_BUFFER;