History

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

Linus Torvalds committed 5 years ago

Commit 7c0ec892 parents 5ff2756 1bb56815 files · +150 −57Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t