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 branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull SMB3 fixes from Steve French:
"A collection of CIFS/SMB3 fixes.

It includes a couple bug fixes, a few for improved debugging of
cifs.ko and some improvements to the way cifs does key generation.

I do have some additional bug fixes I expect in the next week or two
(to address a problem found by xfstest, and some fixes for SMB3.11
dialect, and a couple patches that just came in yesterday that I am
reviewing)"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
cifs_dbg() outputs an uninitialized buffer in cifs_readdir()
cifs: fix race between call_async() and reconnect()
Prepare for encryption support (first part). Add decryption and encryption key generation. Thanks to Metze for helping with this.
cifs: Allow using O_DIRECT with cache=loose
cifs: Make echo interval tunable
cifs: Check uniqueid for SMB2+ and return -ESTALE if necessary
Print IP address of unresponsive server
cifs: Ratelimit kernel log messages

+238 -52
+1 -1
fs/cifs/cifs_debug.c
··· 50 50 vaf.fmt = fmt; 51 51 vaf.va = &args; 52 52 53 - pr_err("CIFS VFS: %pV", &vaf); 53 + pr_err_ratelimited("CIFS VFS: %pV", &vaf); 54 54 55 55 va_end(args); 56 56 }
+4 -5
fs/cifs/cifs_debug.h
··· 51 51 /* information message: e.g., configuration, major event */ 52 52 #define cifs_dbg(type, fmt, ...) \ 53 53 do { \ 54 - if (type == FYI) { \ 55 - if (cifsFYI & CIFS_INFO) { \ 56 - pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__); \ 57 - } \ 54 + if (type == FYI && cifsFYI & CIFS_INFO) { \ 55 + pr_debug_ratelimited("%s: " \ 56 + fmt, __FILE__, ##__VA_ARGS__); \ 58 57 } else if (type == VFS) { \ 59 58 cifs_vfs_err(fmt, ##__VA_ARGS__); \ 60 59 } else if (type == NOISY && type != 0) { \ 61 - pr_debug(fmt, ##__VA_ARGS__); \ 60 + pr_debug_ratelimited(fmt, ##__VA_ARGS__); \ 62 61 } \ 63 62 } while (0) 64 63
+17
fs/cifs/cifsfs.c
··· 507 507 508 508 seq_printf(s, ",rsize=%u", cifs_sb->rsize); 509 509 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 510 + seq_printf(s, ",echo_interval=%lu", 511 + tcon->ses->server->echo_interval / HZ); 510 512 /* convert actimeo and display it in seconds */ 511 513 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); 512 514 ··· 754 752 ssize_t rc; 755 753 struct inode *inode = file_inode(iocb->ki_filp); 756 754 755 + if (iocb->ki_filp->f_flags & O_DIRECT) 756 + return cifs_user_readv(iocb, iter); 757 + 757 758 rc = cifs_revalidate_mapping(inode); 758 759 if (rc) 759 760 return rc; ··· 770 765 struct cifsInodeInfo *cinode = CIFS_I(inode); 771 766 ssize_t written; 772 767 int rc; 768 + 769 + if (iocb->ki_filp->f_flags & O_DIRECT) { 770 + written = cifs_user_writev(iocb, from); 771 + if (written > 0 && CIFS_CACHE_READ(cinode)) { 772 + cifs_zap_mapping(inode); 773 + cifs_dbg(FYI, 774 + "Set no oplock for inode=%p after a write operation\n", 775 + inode); 776 + cinode->oplock = 0; 777 + } 778 + return written; 779 + } 773 780 774 781 written = cifs_get_writer(cinode); 775 782 if (written)
+12 -4
fs/cifs/cifsglob.h
··· 70 70 #define SERVER_NAME_LENGTH 40 71 71 #define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) 72 72 73 - /* SMB echo "timeout" -- FIXME: tunable? */ 74 - #define SMB_ECHO_INTERVAL (60 * HZ) 73 + /* echo interval in seconds */ 74 + #define SMB_ECHO_INTERVAL_MIN 1 75 + #define SMB_ECHO_INTERVAL_MAX 600 76 + #define SMB_ECHO_INTERVAL_DEFAULT 60 75 77 76 78 #include "cifspdu.h" 77 79 ··· 227 225 void (*print_stats)(struct seq_file *m, struct cifs_tcon *); 228 226 void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *); 229 227 /* verify the message */ 230 - int (*check_message)(char *, unsigned int); 228 + int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); 231 229 bool (*is_oplock_break)(char *, struct TCP_Server_Info *); 232 230 void (*downgrade_oplock)(struct TCP_Server_Info *, 233 231 struct cifsInodeInfo *, bool); ··· 509 507 struct sockaddr_storage dstaddr; /* destination address */ 510 508 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 511 509 struct nls_table *local_nls; 510 + unsigned int echo_interval; /* echo interval in secs */ 512 511 }; 513 512 514 513 #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \ ··· 630 627 #ifdef CONFIG_CIFS_SMB2 631 628 unsigned int max_read; 632 629 unsigned int max_write; 630 + __u8 preauth_hash[512]; 633 631 #endif /* CONFIG_CIFS_SMB2 */ 632 + unsigned long echo_interval; 634 633 }; 635 634 636 635 static inline unsigned int ··· 814 809 bool need_reconnect:1; /* connection reset, uid now invalid */ 815 810 #ifdef CONFIG_CIFS_SMB2 816 811 __u16 session_flags; 817 - char smb3signingkey[SMB3_SIGN_KEY_SIZE]; /* for signing smb3 packets */ 812 + __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; 813 + __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; 814 + __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; 815 + __u8 preauth_hash[512]; 818 816 #endif /* CONFIG_CIFS_SMB2 */ 819 817 }; 820 818
+3 -2
fs/cifs/cifsproto.h
··· 102 102 struct smb_hdr *out_buf, 103 103 int *bytes_returned); 104 104 extern int cifs_reconnect(struct TCP_Server_Info *server); 105 - extern int checkSMB(char *buf, unsigned int length); 105 + extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr); 106 106 extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *); 107 107 extern bool backup_cred(struct cifs_sb_info *); 108 108 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); ··· 439 439 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); 440 440 extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 441 441 extern int calc_seckey(struct cifs_ses *); 442 - extern int generate_smb3signingkey(struct cifs_ses *); 442 + extern int generate_smb30signingkey(struct cifs_ses *); 443 + extern int generate_smb311signingkey(struct cifs_ses *); 443 444 444 445 #ifdef CONFIG_CIFS_WEAK_PW_HASH 445 446 extern int calc_lanman_hash(const char *password, const char *cryptkey,
+28 -8
fs/cifs/connect.c
··· 95 95 Opt_cruid, Opt_gid, Opt_file_mode, 96 96 Opt_dirmode, Opt_port, 97 97 Opt_rsize, Opt_wsize, Opt_actimeo, 98 + Opt_echo_interval, 98 99 99 100 /* Mount options which take string value */ 100 101 Opt_user, Opt_pass, Opt_ip, ··· 189 188 { Opt_rsize, "rsize=%s" }, 190 189 { Opt_wsize, "wsize=%s" }, 191 190 { Opt_actimeo, "actimeo=%s" }, 191 + { Opt_echo_interval, "echo_interval=%s" }, 192 192 193 193 { Opt_blank_user, "user=" }, 194 194 { Opt_blank_user, "username=" }, ··· 370 368 server->session_key.response = NULL; 371 369 server->session_key.len = 0; 372 370 server->lstrp = jiffies; 373 - mutex_unlock(&server->srv_mutex); 374 371 375 372 /* mark submitted MIDs for retry and issue callback */ 376 373 INIT_LIST_HEAD(&retry_list); ··· 382 381 list_move(&mid_entry->qhead, &retry_list); 383 382 } 384 383 spin_unlock(&GlobalMid_Lock); 384 + mutex_unlock(&server->srv_mutex); 385 385 386 386 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); 387 387 list_for_each_safe(tmp, tmp2, &retry_list) { ··· 420 418 int rc; 421 419 struct TCP_Server_Info *server = container_of(work, 422 420 struct TCP_Server_Info, echo.work); 421 + unsigned long echo_interval = server->echo_interval; 423 422 424 423 /* 425 424 * We cannot send an echo if it is disabled or until the ··· 430 427 */ 431 428 if (!server->ops->need_neg || server->ops->need_neg(server) || 432 429 (server->ops->can_echo && !server->ops->can_echo(server)) || 433 - time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) 430 + time_before(jiffies, server->lstrp + echo_interval - HZ)) 434 431 goto requeue_echo; 435 432 436 433 rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS; ··· 439 436 server->hostname); 440 437 441 438 requeue_echo: 442 - queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL); 439 + queue_delayed_work(cifsiod_wq, &server->echo, echo_interval); 443 440 } 444 441 445 442 static bool ··· 490 487 * a response in >60s. 491 488 */ 492 489 if (server->tcpStatus == CifsGood && 493 - time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) { 494 - cifs_dbg(VFS, "Server %s has not responded in %d seconds. Reconnecting...\n", 495 - server->hostname, (2 * SMB_ECHO_INTERVAL) / HZ); 490 + time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { 491 + cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", 492 + server->hostname, (2 * server->echo_interval) / HZ); 496 493 cifs_reconnect(server); 497 494 wake_up(&server->response_q); 498 495 return true; ··· 831 828 * 48 bytes is enough to display the header and a little bit 832 829 * into the payload for debugging purposes. 833 830 */ 834 - length = server->ops->check_message(buf, server->total_read); 831 + length = server->ops->check_message(buf, server->total_read, server); 835 832 if (length != 0) 836 833 cifs_dump_mem("Bad SMB: ", buf, 837 834 min_t(unsigned int, server->total_read, 48)); ··· 1627 1624 goto cifs_parse_mount_err; 1628 1625 } 1629 1626 break; 1627 + case Opt_echo_interval: 1628 + if (get_option_ul(args, &option)) { 1629 + cifs_dbg(VFS, "%s: Invalid echo interval value\n", 1630 + __func__); 1631 + goto cifs_parse_mount_err; 1632 + } 1633 + vol->echo_interval = option; 1634 + break; 1630 1635 1631 1636 /* String Arguments */ 1632 1637 ··· 2100 2089 if (!match_security(server, vol)) 2101 2090 return 0; 2102 2091 2092 + if (server->echo_interval != vol->echo_interval) 2093 + return 0; 2094 + 2103 2095 return 1; 2104 2096 } 2105 2097 ··· 2222 2208 tcp_ses->tcpStatus = CifsNew; 2223 2209 ++tcp_ses->srv_count; 2224 2210 2211 + if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN && 2212 + volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX) 2213 + tcp_ses->echo_interval = volume_info->echo_interval * HZ; 2214 + else 2215 + tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ; 2216 + 2225 2217 rc = ip_connect(tcp_ses); 2226 2218 if (rc < 0) { 2227 2219 cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n"); ··· 2257 2237 cifs_fscache_get_client_cookie(tcp_ses); 2258 2238 2259 2239 /* queue echo request delayed work */ 2260 - queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL); 2240 + queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); 2261 2241 2262 2242 return tcp_ses; 2263 2243
+22 -2
fs/cifs/inode.c
··· 814 814 } 815 815 } else 816 816 fattr.cf_uniqueid = iunique(sb, ROOT_I); 817 - } else 818 - fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; 817 + } else { 818 + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && 819 + validinum == false && server->ops->get_srv_inum) { 820 + /* 821 + * Pass a NULL tcon to ensure we don't make a round 822 + * trip to the server. This only works for SMB2+. 823 + */ 824 + tmprc = server->ops->get_srv_inum(xid, 825 + NULL, cifs_sb, full_path, 826 + &fattr.cf_uniqueid, data); 827 + if (tmprc) 828 + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; 829 + } else 830 + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; 831 + } 819 832 820 833 /* query for SFU type info if supported and needed */ 821 834 if (fattr.cf_cifsattrs & ATTR_SYSTEM && ··· 868 855 rc = -ENOMEM; 869 856 } else { 870 857 /* we already have inode, update it */ 858 + 859 + /* if uniqueid is different, return error */ 860 + if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && 861 + CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { 862 + rc = -ESTALE; 863 + goto cgii_exit; 864 + } 871 865 872 866 /* if filetype is different, return error */ 873 867 if (unlikely(((*inode)->i_mode & S_IFMT) !=
+1 -1
fs/cifs/misc.c
··· 310 310 } 311 311 312 312 int 313 - checkSMB(char *buf, unsigned int total_read) 313 + checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server) 314 314 { 315 315 struct smb_hdr *smb = (struct smb_hdr *)buf; 316 316 __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
+1
fs/cifs/readdir.c
··· 847 847 * if buggy server returns . and .. late do we want to 848 848 * check for that here? 849 849 */ 850 + *tmp_buf = 0; 850 851 rc = cifs_filldir(current_entry, file, ctx, 851 852 tmp_buf, max_len); 852 853 if (rc) {
+30 -6
fs/cifs/smb2misc.c
··· 38 38 * Make sure that this really is an SMB, that it is a response, 39 39 * and that the message ids match. 40 40 */ 41 - if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) && 41 + if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) && 42 42 (mid == wire_mid)) { 43 43 if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR) 44 44 return 0; ··· 50 50 cifs_dbg(VFS, "Received Request not response\n"); 51 51 } 52 52 } else { /* bad signature or mid */ 53 - if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER) 53 + if (hdr->ProtocolId != SMB2_PROTO_NUMBER) 54 54 cifs_dbg(VFS, "Bad protocol string signature header %x\n", 55 - *(unsigned int *) hdr->ProtocolId); 55 + le32_to_cpu(hdr->ProtocolId)); 56 56 if (mid != wire_mid) 57 57 cifs_dbg(VFS, "Mids do not match: %llu and %llu\n", 58 58 mid, wire_mid); ··· 93 93 }; 94 94 95 95 int 96 - smb2_check_message(char *buf, unsigned int length) 96 + smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) 97 97 { 98 98 struct smb2_hdr *hdr = (struct smb2_hdr *)buf; 99 99 struct smb2_pdu *pdu = (struct smb2_pdu *)hdr; 100 - __u64 mid = le64_to_cpu(hdr->MessageId); 100 + __u64 mid; 101 101 __u32 len = get_rfc1002_length(buf); 102 102 __u32 clc_len; /* calculated length */ 103 103 int command; ··· 111 111 * ie Validate the wct via smb2_struct_sizes table above 112 112 */ 113 113 114 + if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { 115 + struct smb2_transform_hdr *thdr = 116 + (struct smb2_transform_hdr *)buf; 117 + struct cifs_ses *ses = NULL; 118 + struct list_head *tmp; 119 + 120 + /* decrypt frame now that it is completely read in */ 121 + spin_lock(&cifs_tcp_ses_lock); 122 + list_for_each(tmp, &srvr->smb_ses_list) { 123 + ses = list_entry(tmp, struct cifs_ses, smb_ses_list); 124 + if (ses->Suid == thdr->SessionId) 125 + break; 126 + 127 + ses = NULL; 128 + } 129 + spin_unlock(&cifs_tcp_ses_lock); 130 + if (ses == NULL) { 131 + cifs_dbg(VFS, "no decryption - session id not found\n"); 132 + return 1; 133 + } 134 + } 135 + 136 + 137 + mid = le64_to_cpu(hdr->MessageId); 114 138 if (length < sizeof(struct smb2_pdu)) { 115 139 if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) { 116 140 pdu->StructureSize2 = 0; ··· 346 322 347 323 /* return pointer to beginning of data area, ie offset from SMB start */ 348 324 if ((*off != 0) && (*len != 0)) 349 - return (char *)(&hdr->ProtocolId[0]) + *off; 325 + return (char *)(&hdr->ProtocolId) + *off; 350 326 else 351 327 return NULL; 352 328 }
+9 -4
fs/cifs/smb2ops.c
··· 182 182 struct smb2_hdr *hdr = (struct smb2_hdr *)buf; 183 183 __u64 wire_mid = le64_to_cpu(hdr->MessageId); 184 184 185 + if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { 186 + cifs_dbg(VFS, "encrypted frame parsing not supported yet"); 187 + return NULL; 188 + } 189 + 185 190 spin_lock(&GlobalMid_Lock); 186 191 list_for_each_entry(mid, &server->pending_mid_q, qhead) { 187 192 if ((mid->mid == wire_mid) && ··· 1697 1692 .get_lease_key = smb2_get_lease_key, 1698 1693 .set_lease_key = smb2_set_lease_key, 1699 1694 .new_lease_key = smb2_new_lease_key, 1700 - .generate_signingkey = generate_smb3signingkey, 1695 + .generate_signingkey = generate_smb30signingkey, 1701 1696 .calc_signature = smb3_calc_signature, 1702 1697 .set_integrity = smb3_set_integrity, 1703 1698 .is_read_op = smb21_is_read_op, ··· 1784 1779 .get_lease_key = smb2_get_lease_key, 1785 1780 .set_lease_key = smb2_set_lease_key, 1786 1781 .new_lease_key = smb2_new_lease_key, 1787 - .generate_signingkey = generate_smb3signingkey, 1782 + .generate_signingkey = generate_smb311signingkey, 1788 1783 .calc_signature = smb3_calc_signature, 1789 1784 .set_integrity = smb3_set_integrity, 1790 1785 .is_read_op = smb21_is_read_op, ··· 1843 1838 struct smb_version_values smb30_values = { 1844 1839 .version_string = SMB30_VERSION_STRING, 1845 1840 .protocol_id = SMB30_PROT_ID, 1846 - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, 1841 + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, 1847 1842 .large_lock_type = 0, 1848 1843 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 1849 1844 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, ··· 1863 1858 struct smb_version_values smb302_values = { 1864 1859 .version_string = SMB302_VERSION_STRING, 1865 1860 .protocol_id = SMB302_PROT_ID, 1866 - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, 1861 + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, 1867 1862 .large_lock_type = 0, 1868 1863 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 1869 1864 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
+4 -6
fs/cifs/smb2pdu.c
··· 97 97 hdr->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr) 98 98 - 4 /* RFC 1001 length field itself not counted */); 99 99 100 - hdr->ProtocolId[0] = 0xFE; 101 - hdr->ProtocolId[1] = 'S'; 102 - hdr->ProtocolId[2] = 'M'; 103 - hdr->ProtocolId[3] = 'B'; 100 + hdr->ProtocolId = SMB2_PROTO_NUMBER; 104 101 hdr->StructureSize = cpu_to_le16(64); 105 102 hdr->Command = smb2_cmd; 106 103 hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */ ··· 1570 1573 goto ioctl_exit; 1571 1574 } 1572 1575 1573 - memcpy(*out_data, rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset), 1576 + memcpy(*out_data, 1577 + (char *)&rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset), 1574 1578 *plen); 1575 1579 ioctl_exit: 1576 1580 free_rsp_buf(resp_buftype, rsp); ··· 2091 2093 } 2092 2094 2093 2095 if (*buf) { 2094 - memcpy(*buf, (char *)rsp->hdr.ProtocolId + rsp->DataOffset, 2096 + memcpy(*buf, (char *)&rsp->hdr.ProtocolId + rsp->DataOffset, 2095 2097 *nbytes); 2096 2098 free_rsp_buf(resp_buftype, iov[0].iov_base); 2097 2099 } else if (resp_buftype != CIFS_NO_BUFFER) {
+4 -4
fs/cifs/smb2pdu.h
··· 86 86 #define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */ 87 87 88 88 #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) 89 + #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) 89 90 90 91 /* 91 92 * SMB2 Header Definition ··· 103 102 __be32 smb2_buf_length; /* big endian on wire */ 104 103 /* length is only two or three bytes - with 105 104 one or two byte type preceding it that MBZ */ 106 - __u8 ProtocolId[4]; /* 0xFE 'S' 'M' 'B' */ 105 + __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */ 107 106 __le16 StructureSize; /* 64 */ 108 107 __le16 CreditCharge; /* MBZ */ 109 108 __le32 Status; /* Error from server */ ··· 129 128 one or two byte type preceding it that MBZ */ 130 129 __u8 ProtocolId[4]; /* 0xFD 'S' 'M' 'B' */ 131 130 __u8 Signature[16]; 132 - __u8 Nonce[11]; 133 - __u8 Reserved[5]; 131 + __u8 Nonce[16]; 134 132 __le32 OriginalMessageSize; 135 133 __u16 Reserved1; 136 - __le16 EncryptionAlgorithm; 134 + __le16 Flags; /* EncryptionAlgorithm */ 137 135 __u64 SessionId; 138 136 } __packed; 139 137
+2 -1
fs/cifs/smb2proto.h
··· 34 34 ***************************************************************** 35 35 */ 36 36 extern int map_smb2_to_linux_error(char *buf, bool log_err); 37 - extern int smb2_check_message(char *buf, unsigned int length); 37 + extern int smb2_check_message(char *buf, unsigned int length, 38 + struct TCP_Server_Info *server); 38 39 extern unsigned int smb2_calc_size(void *buf); 39 40 extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr); 40 41 extern __le16 *cifs_convert_path_to_utf16(const char *from,
+96 -6
fs/cifs/smb2transport.c
··· 222 222 return rc; 223 223 } 224 224 225 - int 226 - generate_smb3signingkey(struct cifs_ses *ses) 225 + static int generate_key(struct cifs_ses *ses, struct kvec label, 226 + struct kvec context, __u8 *key, unsigned int key_size) 227 227 { 228 228 unsigned char zero = 0x0; 229 229 __u8 i[4] = {0, 0, 0, 1}; ··· 233 233 unsigned char *hashptr = prfhash; 234 234 235 235 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); 236 - memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE); 236 + memset(key, 0x0, key_size); 237 237 238 238 rc = smb3_crypto_shash_allocate(ses->server); 239 239 if (rc) { ··· 262 262 } 263 263 264 264 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 265 - "SMB2AESCMAC", 12); 265 + label.iov_base, label.iov_len); 266 266 if (rc) { 267 267 cifs_dbg(VFS, "%s: Could not update with label\n", __func__); 268 268 goto smb3signkey_ret; ··· 276 276 } 277 277 278 278 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 279 - "SmbSign", 8); 279 + context.iov_base, context.iov_len); 280 280 if (rc) { 281 281 cifs_dbg(VFS, "%s: Could not update with context\n", __func__); 282 282 goto smb3signkey_ret; ··· 296 296 goto smb3signkey_ret; 297 297 } 298 298 299 - memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE); 299 + memcpy(key, hashptr, key_size); 300 300 301 301 smb3signkey_ret: 302 302 return rc; 303 + } 304 + 305 + struct derivation { 306 + struct kvec label; 307 + struct kvec context; 308 + }; 309 + 310 + struct derivation_triplet { 311 + struct derivation signing; 312 + struct derivation encryption; 313 + struct derivation decryption; 314 + }; 315 + 316 + static int 317 + generate_smb3signingkey(struct cifs_ses *ses, 318 + const struct derivation_triplet *ptriplet) 319 + { 320 + int rc; 321 + 322 + rc = generate_key(ses, ptriplet->signing.label, 323 + ptriplet->signing.context, ses->smb3signingkey, 324 + SMB3_SIGN_KEY_SIZE); 325 + if (rc) 326 + return rc; 327 + 328 + rc = generate_key(ses, ptriplet->encryption.label, 329 + ptriplet->encryption.context, ses->smb3encryptionkey, 330 + SMB3_SIGN_KEY_SIZE); 331 + if (rc) 332 + return rc; 333 + 334 + return generate_key(ses, ptriplet->decryption.label, 335 + ptriplet->decryption.context, 336 + ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE); 337 + } 338 + 339 + int 340 + generate_smb30signingkey(struct cifs_ses *ses) 341 + 342 + { 343 + struct derivation_triplet triplet; 344 + struct derivation *d; 345 + 346 + d = &triplet.signing; 347 + d->label.iov_base = "SMB2AESCMAC"; 348 + d->label.iov_len = 12; 349 + d->context.iov_base = "SmbSign"; 350 + d->context.iov_len = 8; 351 + 352 + d = &triplet.encryption; 353 + d->label.iov_base = "SMB2AESCCM"; 354 + d->label.iov_len = 11; 355 + d->context.iov_base = "ServerIn "; 356 + d->context.iov_len = 10; 357 + 358 + d = &triplet.decryption; 359 + d->label.iov_base = "SMB2AESCCM"; 360 + d->label.iov_len = 11; 361 + d->context.iov_base = "ServerOut"; 362 + d->context.iov_len = 10; 363 + 364 + return generate_smb3signingkey(ses, &triplet); 365 + } 366 + 367 + int 368 + generate_smb311signingkey(struct cifs_ses *ses) 369 + 370 + { 371 + struct derivation_triplet triplet; 372 + struct derivation *d; 373 + 374 + d = &triplet.signing; 375 + d->label.iov_base = "SMB2AESCMAC"; 376 + d->label.iov_len = 12; 377 + d->context.iov_base = "SmbSign"; 378 + d->context.iov_len = 8; 379 + 380 + d = &triplet.encryption; 381 + d->label.iov_base = "SMB2AESCCM"; 382 + d->label.iov_len = 11; 383 + d->context.iov_base = "ServerIn "; 384 + d->context.iov_len = 10; 385 + 386 + d = &triplet.decryption; 387 + d->label.iov_base = "SMB2AESCCM"; 388 + d->label.iov_len = 11; 389 + d->context.iov_base = "ServerOut"; 390 + d->context.iov_len = 10; 391 + 392 + return generate_smb3signingkey(ses, &triplet); 303 393 } 304 394 305 395 int
+4 -2
fs/cifs/transport.c
··· 576 576 cifs_in_send_dec(server); 577 577 cifs_save_when_sent(mid); 578 578 579 - if (rc < 0) 579 + if (rc < 0) { 580 580 server->sequence_number -= 2; 581 + cifs_delete_mid(mid); 582 + } 583 + 581 584 mutex_unlock(&server->srv_mutex); 582 585 583 586 if (rc == 0) 584 587 return 0; 585 588 586 - cifs_delete_mid(mid); 587 589 add_credits_and_wake_if(server, credits, optype); 588 590 return rc; 589 591 }