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 '5.13-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"Three SMB3 fixes.

Two for stable, and the other fixes a problem pointed out with a
recently added ioctl"

* tag '5.13-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6:
cifs: change format of CIFS_FULL_KEY_DUMP ioctl
cifs: fix string declarations and assignments in tracepoints
cifs: set server->cipher_type to AES-128-CCM for SMB3.0

+149 -56
+19 -6
fs/cifs/cifs_ioctl.h
··· 72 72 } __packed; 73 73 74 74 /* 75 - * Dump full key (32 byte encrypt/decrypt keys instead of 16 bytes) 76 - * is needed if GCM256 (stronger encryption) negotiated 75 + * Dump variable-sized keys 77 76 */ 78 77 struct smb3_full_key_debug_info { 79 - __u64 Suid; 78 + /* INPUT: size of userspace buffer */ 79 + __u32 in_size; 80 + 81 + /* 82 + * INPUT: 0 for current user, otherwise session to dump 83 + * OUTPUT: session id that was dumped 84 + */ 85 + __u64 session_id; 80 86 __u16 cipher_type; 81 - __u8 auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */ 82 - __u8 smb3encryptionkey[32]; /* SMB3_ENC_DEC_KEY_SIZE */ 83 - __u8 smb3decryptionkey[32]; /* SMB3_ENC_DEC_KEY_SIZE */ 87 + __u8 session_key_length; 88 + __u8 server_in_key_length; 89 + __u8 server_out_key_length; 90 + __u8 data[]; 91 + /* 92 + * return this struct with the keys appended at the end: 93 + * __u8 session_key[session_key_length]; 94 + * __u8 server_in_key[server_in_key_length]; 95 + * __u8 server_out_key[server_out_key_length]; 96 + */ 84 97 } __packed; 85 98 86 99 struct smb3_notify {
+2 -1
fs/cifs/cifspdu.h
··· 148 148 #define SMB3_SIGN_KEY_SIZE (16) 149 149 150 150 /* 151 - * Size of the smb3 encryption/decryption keys 151 + * Size of the smb3 encryption/decryption key storage. 152 + * This size is big enough to store any cipher key types. 152 153 */ 153 154 #define SMB3_ENC_DEC_KEY_SIZE (32) 154 155
+104 -37
fs/cifs/ioctl.c
··· 33 33 #include "cifsfs.h" 34 34 #include "cifs_ioctl.h" 35 35 #include "smb2proto.h" 36 + #include "smb2glob.h" 36 37 #include <linux/btrfs.h> 37 38 38 39 static long cifs_ioctl_query_info(unsigned int xid, struct file *filep, ··· 215 214 return 0; 216 215 } 217 216 218 - static int cifs_dump_full_key(struct cifs_tcon *tcon, unsigned long arg) 217 + static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug_info __user *in) 219 218 { 220 - struct smb3_full_key_debug_info pfull_key_inf; 221 - __u64 suid; 222 - struct list_head *tmp; 219 + struct smb3_full_key_debug_info out; 223 220 struct cifs_ses *ses; 221 + int rc = 0; 224 222 bool found = false; 223 + u8 __user *end; 225 224 226 - if (!smb3_encryption_required(tcon)) 227 - return -EOPNOTSUPP; 225 + if (!smb3_encryption_required(tcon)) { 226 + rc = -EOPNOTSUPP; 227 + goto out; 228 + } 228 229 229 - ses = tcon->ses; /* default to user id for current user */ 230 - if (get_user(suid, (__u64 __user *)arg)) 231 - suid = 0; 232 - if (suid) { 233 - /* search to see if there is a session with a matching SMB UID */ 230 + /* copy user input into our output buffer */ 231 + if (copy_from_user(&out, in, sizeof(out))) { 232 + rc = -EINVAL; 233 + goto out; 234 + } 235 + 236 + if (!out.session_id) { 237 + /* if ses id is 0, use current user session */ 238 + ses = tcon->ses; 239 + } else { 240 + /* otherwise if a session id is given, look for it in all our sessions */ 241 + struct cifs_ses *ses_it = NULL; 242 + struct TCP_Server_Info *server_it = NULL; 243 + 234 244 spin_lock(&cifs_tcp_ses_lock); 235 - list_for_each(tmp, &tcon->ses->server->smb_ses_list) { 236 - ses = list_entry(tmp, struct cifs_ses, smb_ses_list); 237 - if (ses->Suid == suid) { 238 - found = true; 239 - break; 245 + list_for_each_entry(server_it, &cifs_tcp_ses_list, tcp_ses_list) { 246 + list_for_each_entry(ses_it, &server_it->smb_ses_list, smb_ses_list) { 247 + if (ses_it->Suid == out.session_id) { 248 + ses = ses_it; 249 + /* 250 + * since we are using the session outside the crit 251 + * section, we need to make sure it won't be released 252 + * so increment its refcount 253 + */ 254 + ses->ses_count++; 255 + found = true; 256 + goto search_end; 257 + } 240 258 } 241 259 } 260 + search_end: 242 261 spin_unlock(&cifs_tcp_ses_lock); 243 - if (found == false) 244 - return -EINVAL; 245 - } /* else uses default user's SMB UID (ie current user) */ 262 + if (!found) { 263 + rc = -ENOENT; 264 + goto out; 265 + } 266 + } 246 267 247 - pfull_key_inf.cipher_type = le16_to_cpu(ses->server->cipher_type); 248 - pfull_key_inf.Suid = ses->Suid; 249 - memcpy(pfull_key_inf.auth_key, ses->auth_key.response, 250 - 16 /* SMB2_NTLMV2_SESSKEY_SIZE */); 251 - memcpy(pfull_key_inf.smb3decryptionkey, ses->smb3decryptionkey, 252 - 32 /* SMB3_ENC_DEC_KEY_SIZE */); 253 - memcpy(pfull_key_inf.smb3encryptionkey, 254 - ses->smb3encryptionkey, 32 /* SMB3_ENC_DEC_KEY_SIZE */); 255 - if (copy_to_user((void __user *)arg, &pfull_key_inf, 256 - sizeof(struct smb3_full_key_debug_info))) 257 - return -EFAULT; 268 + switch (ses->server->cipher_type) { 269 + case SMB2_ENCRYPTION_AES128_CCM: 270 + case SMB2_ENCRYPTION_AES128_GCM: 271 + out.session_key_length = CIFS_SESS_KEY_SIZE; 272 + out.server_in_key_length = out.server_out_key_length = SMB3_GCM128_CRYPTKEY_SIZE; 273 + break; 274 + case SMB2_ENCRYPTION_AES256_CCM: 275 + case SMB2_ENCRYPTION_AES256_GCM: 276 + out.session_key_length = CIFS_SESS_KEY_SIZE; 277 + out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE; 278 + break; 279 + default: 280 + rc = -EOPNOTSUPP; 281 + goto out; 282 + } 258 283 259 - return 0; 284 + /* check if user buffer is big enough to store all the keys */ 285 + if (out.in_size < sizeof(out) + out.session_key_length + out.server_in_key_length 286 + + out.server_out_key_length) { 287 + rc = -ENOBUFS; 288 + goto out; 289 + } 290 + 291 + out.session_id = ses->Suid; 292 + out.cipher_type = le16_to_cpu(ses->server->cipher_type); 293 + 294 + /* overwrite user input with our output */ 295 + if (copy_to_user(in, &out, sizeof(out))) { 296 + rc = -EINVAL; 297 + goto out; 298 + } 299 + 300 + /* append all the keys at the end of the user buffer */ 301 + end = in->data; 302 + if (copy_to_user(end, ses->auth_key.response, out.session_key_length)) { 303 + rc = -EINVAL; 304 + goto out; 305 + } 306 + end += out.session_key_length; 307 + 308 + if (copy_to_user(end, ses->smb3encryptionkey, out.server_in_key_length)) { 309 + rc = -EINVAL; 310 + goto out; 311 + } 312 + end += out.server_in_key_length; 313 + 314 + if (copy_to_user(end, ses->smb3decryptionkey, out.server_out_key_length)) { 315 + rc = -EINVAL; 316 + goto out; 317 + } 318 + 319 + out: 320 + if (found) 321 + cifs_put_smb_ses(ses); 322 + return rc; 260 323 } 261 324 262 325 long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) ··· 436 371 rc = -EOPNOTSUPP; 437 372 break; 438 373 case CIFS_DUMP_KEY: 374 + /* 375 + * Dump encryption keys. This is an old ioctl that only 376 + * handles AES-128-{CCM,GCM}. 377 + */ 439 378 if (pSMBFile == NULL) 440 379 break; 441 380 if (!capable(CAP_SYS_ADMIN)) { ··· 467 398 else 468 399 rc = 0; 469 400 break; 470 - /* 471 - * Dump full key (32 bytes instead of 16 bytes) is 472 - * needed if GCM256 (stronger encryption) negotiated 473 - */ 474 401 case CIFS_DUMP_FULL_KEY: 402 + /* 403 + * Dump encryption keys (handles any key sizes) 404 + */ 475 405 if (pSMBFile == NULL) 476 406 break; 477 407 if (!capable(CAP_SYS_ADMIN)) { ··· 478 410 break; 479 411 } 480 412 tcon = tlink_tcon(pSMBFile->tlink); 481 - rc = cifs_dump_full_key(tcon, arg); 482 - 413 + rc = cifs_dump_full_key(tcon, (void __user *)arg); 483 414 break; 484 415 case CIFS_IOC_NOTIFY: 485 416 if (!S_ISDIR(inode->i_mode)) {
+7
fs/cifs/smb2pdu.c
··· 958 958 /* Internal types */ 959 959 server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES; 960 960 961 + /* 962 + * SMB3.0 supports only 1 cipher and doesn't have a encryption neg context 963 + * Set the cipher type manually. 964 + */ 965 + if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) 966 + server->cipher_type = SMB2_ENCRYPTION_AES128_CCM; 967 + 961 968 security_blob = smb2_get_data_area_len(&blob_offset, &blob_length, 962 969 (struct smb2_sync_hdr *)rsp); 963 970 /*
+17 -12
fs/cifs/trace.h
··· 12 12 13 13 #include <linux/tracepoint.h> 14 14 15 + /* 16 + * Please use this 3-part article as a reference for writing new tracepoints: 17 + * https://lwn.net/Articles/379903/ 18 + */ 19 + 15 20 /* For logging errors in read or write */ 16 21 DECLARE_EVENT_CLASS(smb3_rw_err_class, 17 22 TP_PROTO(unsigned int xid, ··· 534 529 TP_ARGS(xid, func_name, rc), 535 530 TP_STRUCT__entry( 536 531 __field(unsigned int, xid) 537 - __field(const char *, func_name) 532 + __string(func_name, func_name) 538 533 __field(int, rc) 539 534 ), 540 535 TP_fast_assign( 541 536 __entry->xid = xid; 542 - __entry->func_name = func_name; 537 + __assign_str(func_name, func_name); 543 538 __entry->rc = rc; 544 539 ), 545 540 TP_printk("\t%s: xid=%u rc=%d", 546 - __entry->func_name, __entry->xid, __entry->rc) 541 + __get_str(func_name), __entry->xid, __entry->rc) 547 542 ) 548 543 549 544 #define DEFINE_SMB3_EXIT_ERR_EVENT(name) \ ··· 588 583 TP_ARGS(xid, func_name), 589 584 TP_STRUCT__entry( 590 585 __field(unsigned int, xid) 591 - __field(const char *, func_name) 586 + __string(func_name, func_name) 592 587 ), 593 588 TP_fast_assign( 594 589 __entry->xid = xid; 595 - __entry->func_name = func_name; 590 + __assign_str(func_name, func_name); 596 591 ), 597 592 TP_printk("\t%s: xid=%u", 598 - __entry->func_name, __entry->xid) 593 + __get_str(func_name), __entry->xid) 599 594 ) 600 595 601 596 #define DEFINE_SMB3_ENTER_EXIT_EVENT(name) \ ··· 862 857 TP_STRUCT__entry( 863 858 __field(__u64, currmid) 864 859 __field(__u64, conn_id) 865 - __field(char *, hostname) 860 + __string(hostname, hostname) 866 861 ), 867 862 TP_fast_assign( 868 863 __entry->currmid = currmid; 869 864 __entry->conn_id = conn_id; 870 - __entry->hostname = hostname; 865 + __assign_str(hostname, hostname); 871 866 ), 872 867 TP_printk("conn_id=0x%llx server=%s current_mid=%llu", 873 868 __entry->conn_id, 874 - __entry->hostname, 869 + __get_str(hostname), 875 870 __entry->currmid) 876 871 ) 877 872 ··· 896 891 TP_STRUCT__entry( 897 892 __field(__u64, currmid) 898 893 __field(__u64, conn_id) 899 - __field(char *, hostname) 894 + __string(hostname, hostname) 900 895 __field(int, credits) 901 896 __field(int, credits_to_add) 902 897 __field(int, in_flight) ··· 904 899 TP_fast_assign( 905 900 __entry->currmid = currmid; 906 901 __entry->conn_id = conn_id; 907 - __entry->hostname = hostname; 902 + __assign_str(hostname, hostname); 908 903 __entry->credits = credits; 909 904 __entry->credits_to_add = credits_to_add; 910 905 __entry->in_flight = in_flight; ··· 912 907 TP_printk("conn_id=0x%llx server=%s current_mid=%llu " 913 908 "credits=%d credit_change=%d in_flight=%d", 914 909 __entry->conn_id, 915 - __entry->hostname, 910 + __get_str(hostname), 916 911 __entry->currmid, 917 912 __entry->credits, 918 913 __entry->credits_to_add,