Skip to content

Commit 7edee52

Browse files
committed
Merge tag '5.4-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull more cifs updates from Steve French: "Fixes from the recent SMB3 Test events and Storage Developer Conference (held the last two weeks). Here are nine smb3 patches including an important patch for debugging traces with wireshark, with three patches marked for stable. Additional fixes from last week to better handle some newly discovered reparse points, and a fix the create/mkdir path for setting the mode more atomically (in SMB3 Create security descriptor context), and one for path name processing are still being tested so are not included here" * tag '5.4-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: CIFS: Fix oplock handling for SMB 2.1+ protocols smb3: missing ACL related flags smb3: pass mode bits into create calls smb3: Add missing reparse tags CIFS: fix max ea value size fs/cifs/sess.c: Remove set but not used variable 'capabilities' fs/cifs/smb2pdu.c: Make SMB2_notify_init static smb3: fix leak in "open on server" perf counter smb3: allow decryption keys to be dumped by admin for debugging
2 parents 3f2dc27 + a016e27 commit 7edee52

File tree

14 files changed

+194
-26
lines changed

14 files changed

+194
-26
lines changed

fs/cifs/cifs_ioctl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,18 @@ struct smb_query_info {
5757
/* char buffer[]; */
5858
} __packed;
5959

60+
struct smb3_key_debug_info {
61+
__u64 Suid;
62+
__u16 cipher_type;
63+
__u8 auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
64+
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
65+
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
66+
} __packed;
67+
6068
#define CIFS_IOCTL_MAGIC 0xCF
6169
#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
6270
#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
6371
#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info)
6472
#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
6573
#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
74+
#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)

fs/cifs/cifsacl.h

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,93 @@ struct cifs_acl {
9090
__le32 num_aces;
9191
} __attribute__((packed));
9292

93+
/* ACE types - see MS-DTYP 2.4.4.1 */
94+
#define ACCESS_ALLOWED_ACE_TYPE 0x00
95+
#define ACCESS_DENIED_ACE_TYPE 0x01
96+
#define SYSTEM_AUDIT_ACE_TYPE 0x02
97+
#define SYSTEM_ALARM_ACE_TYPE 0x03
98+
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE 0x04
99+
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
100+
#define ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
101+
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
102+
#define SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
103+
#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x09
104+
#define ACCESS_DENIED_CALLBACK_ACE_TYPE 0x0A
105+
#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0x0B
106+
#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE 0x0C
107+
#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0x0D
108+
#define SYSTEM_ALARM_CALLBACK_ACE_TYPE 0x0E /* Reserved */
109+
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE 0x0F
110+
#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 0x10 /* reserved */
111+
#define SYSTEM_MANDATORY_LABEL_ACE_TYPE 0x11
112+
#define SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE 0x12
113+
#define SYSTEM_SCOPED_POLICY_ID_ACE_TYPE 0x13
114+
115+
/* ACE flags */
116+
#define OBJECT_INHERIT_ACE 0x01
117+
#define CONTAINER_INHERIT_ACE 0x02
118+
#define NO_PROPAGATE_INHERIT_ACE 0x04
119+
#define INHERIT_ONLY_ACE 0x08
120+
#define INHERITED_ACE 0x10
121+
#define SUCCESSFUL_ACCESS_ACE_FLAG 0x40
122+
#define FAILED_ACCESS_ACE_FLAG 0x80
123+
93124
struct cifs_ace {
94-
__u8 type;
125+
__u8 type; /* see above and MS-DTYP 2.4.4.1 */
95126
__u8 flags;
96127
__le16 size;
97128
__le32 access_req;
98129
struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
99130
} __attribute__((packed));
100131

132+
/*
133+
* The current SMB3 form of security descriptor is similar to what was used for
134+
* cifs (see above) but some fields are split, and fields in the struct below
135+
* matches names of fields to the the spec, MS-DTYP (see sections 2.4.5 and
136+
* 2.4.6). Note that "CamelCase" fields are used in this struct in order to
137+
* match the MS-DTYP and MS-SMB2 specs which define the wire format.
138+
*/
139+
struct smb3_sd {
140+
__u8 Revision; /* revision level, MUST be one */
141+
__u8 Sbz1; /* only meaningful if 'RM' flag set below */
142+
__le16 Control;
143+
__le32 OffsetOwner;
144+
__le32 OffsetGroup;
145+
__le32 OffsetSacl;
146+
__le32 OffsetDacl;
147+
} __packed;
148+
149+
/* Meaning of 'Control' field flags */
150+
#define ACL_CONTROL_SR 0x0001 /* Self relative */
151+
#define ACL_CONTROL_RM 0x0002 /* Resource manager control bits */
152+
#define ACL_CONTROL_PS 0x0004 /* SACL protected from inherits */
153+
#define ACL_CONTROL_PD 0x0008 /* DACL protected from inherits */
154+
#define ACL_CONTROL_SI 0x0010 /* SACL Auto-Inherited */
155+
#define ACL_CONTROL_DI 0x0020 /* DACL Auto-Inherited */
156+
#define ACL_CONTROL_SC 0x0040 /* SACL computed through inheritance */
157+
#define ACL_CONTROL_DC 0x0080 /* DACL computed through inheritence */
158+
#define ACL_CONTROL_SS 0x0100 /* Create server ACL */
159+
#define ACL_CONTROL_DT 0x0200 /* DACL provided by trusteed source */
160+
#define ACL_CONTROL_SD 0x0400 /* SACL defaulted */
161+
#define ACL_CONTROL_SP 0x0800 /* SACL is present on object */
162+
#define ACL_CONTROL_DD 0x1000 /* DACL defaulted */
163+
#define ACL_CONTROL_DP 0x2000 /* DACL is present on object */
164+
#define ACL_CONTROL_GD 0x4000 /* Group was defaulted */
165+
#define ACL_CONTROL_OD 0x8000 /* User was defaulted */
166+
167+
/* Meaning of AclRevision flags */
168+
#define ACL_REVISION 0x02 /* See section 2.4.4.1 of MS-DTYP */
169+
#define ACL_REVISION_DS 0x04 /* Additional AceTypes allowed */
170+
171+
struct smb3_acl {
172+
u8 AclRevision; /* revision level */
173+
u8 Sbz1; /* MBZ */
174+
__le16 AclSize;
175+
__le16 AceCount;
176+
__le16 Sbz2; /* MBZ */
177+
} __packed;
178+
179+
101180
/*
102181
* Minimum security identifier can be one for system defined Users
103182
* and Groups such as NULL SID and World or Built-in accounts such

fs/cifs/cifsglob.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ struct smb_version_operations {
331331
umode_t mode, struct cifs_tcon *tcon,
332332
const char *full_path,
333333
struct cifs_sb_info *cifs_sb);
334-
int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *,
335-
struct cifs_sb_info *);
334+
int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode,
335+
struct cifs_tcon *tcon, const char *name,
336+
struct cifs_sb_info *sb);
336337
/* set info on created directory */
337338
void (*mkdir_setinfo)(struct inode *, const char *,
338339
struct cifs_sb_info *, struct cifs_tcon *,
@@ -1209,6 +1210,7 @@ struct cifs_search_info {
12091210
bool smallBuf:1; /* so we know which buf_release function to call */
12101211
};
12111212

1213+
#define ACL_NO_MODE -1
12121214
struct cifs_open_parms {
12131215
struct cifs_tcon *tcon;
12141216
struct cifs_sb_info *cifs_sb;

fs/cifs/cifsproto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid,
372372
const struct nls_table *nls_codepage,
373373
int remap);
374374

375-
extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon,
375+
extern int CIFSSMBMkDir(const unsigned int xid, struct inode *inode,
376+
umode_t mode, struct cifs_tcon *tcon,
376377
const char *name, struct cifs_sb_info *cifs_sb);
377378
extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon,
378379
const char *name, struct cifs_sb_info *cifs_sb);

fs/cifs/cifssmb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,8 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
10781078
}
10791079

10801080
int
1081-
CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1081+
CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1082+
struct cifs_tcon *tcon, const char *name,
10821083
struct cifs_sb_info *cifs_sb)
10831084
{
10841085
int rc = 0;

fs/cifs/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1622,13 +1622,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
16221622
}
16231623

16241624
/* BB add setting the equivalent of mode via CreateX w/ACLs */
1625-
rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb);
1625+
rc = server->ops->mkdir(xid, inode, mode, tcon, full_path, cifs_sb);
16261626
if (rc) {
16271627
cifs_dbg(FYI, "cifs_mkdir returned 0x%x\n", rc);
16281628
d_drop(direntry);
16291629
goto mkdir_out;
16301630
}
16311631

1632+
/* TODO: skip this for smb2/smb3 */
16321633
rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon,
16331634
xid);
16341635
mkdir_out:

fs/cifs/ioctl.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
164164
long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
165165
{
166166
struct inode *inode = file_inode(filep);
167+
struct smb3_key_debug_info pkey_inf;
167168
int rc = -ENOTTY; /* strange error - but the precedent */
168169
unsigned int xid;
169170
struct cifsFileInfo *pSMBFile = filep->private_data;
@@ -270,6 +271,34 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
270271
else
271272
rc = -EOPNOTSUPP;
272273
break;
274+
case CIFS_DUMP_KEY:
275+
if (pSMBFile == NULL)
276+
break;
277+
if (!capable(CAP_SYS_ADMIN)) {
278+
rc = -EACCES;
279+
break;
280+
}
281+
282+
tcon = tlink_tcon(pSMBFile->tlink);
283+
if (!smb3_encryption_required(tcon)) {
284+
rc = -EOPNOTSUPP;
285+
break;
286+
}
287+
pkey_inf.cipher_type =
288+
le16_to_cpu(tcon->ses->server->cipher_type);
289+
pkey_inf.Suid = tcon->ses->Suid;
290+
memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response,
291+
16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
292+
memcpy(pkey_inf.smb3decryptionkey,
293+
tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
294+
memcpy(pkey_inf.smb3encryptionkey,
295+
tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE);
296+
if (copy_to_user((void __user *)arg, &pkey_inf,
297+
sizeof(struct smb3_key_debug_info)))
298+
rc = -EFAULT;
299+
else
300+
rc = 0;
301+
break;
273302
default:
274303
cifs_dbg(FYI, "unsupported ioctl\n");
275304
break;

fs/cifs/sess.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,6 @@ sess_auth_lanman(struct sess_data *sess_data)
698698
char *bcc_ptr;
699699
struct cifs_ses *ses = sess_data->ses;
700700
char lnm_session_key[CIFS_AUTH_RESP_SIZE];
701-
__u32 capabilities;
702701
__u16 bytes_remaining;
703702

704703
/* lanman 2 style sessionsetup */
@@ -709,7 +708,7 @@ sess_auth_lanman(struct sess_data *sess_data)
709708

710709
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
711710
bcc_ptr = sess_data->iov[2].iov_base;
712-
capabilities = cifs_ssetup_hdr(ses, pSMB);
711+
(void)cifs_ssetup_hdr(ses, pSMB);
713712

714713
pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
715714

fs/cifs/smb2inode.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static int
5151
smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
5252
struct cifs_sb_info *cifs_sb, const char *full_path,
5353
__u32 desired_access, __u32 create_disposition,
54-
__u32 create_options, void *ptr, int command,
54+
__u32 create_options, umode_t mode, void *ptr, int command,
5555
struct cifsFileInfo *cfile)
5656
{
5757
int rc;
@@ -103,6 +103,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
103103
oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
104104
oparms.fid = &fid;
105105
oparms.reconnect = false;
106+
oparms.mode = mode;
106107

107108
memset(&open_iov, 0, sizeof(open_iov));
108109
rqst[num_rqst].rq_iov = open_iov;
@@ -478,16 +479,16 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
478479
cifs_get_readable_path(tcon, full_path, &cfile);
479480
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
480481
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
481-
smb2_data, SMB2_OP_QUERY_INFO, cfile);
482+
ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
482483
if (rc == -EOPNOTSUPP) {
483484
*symlink = true;
484485
create_options |= OPEN_REPARSE_POINT;
485486

486487
/* Failed on a symbolic link - query a reparse point info */
487488
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
488489
FILE_READ_ATTRIBUTES, FILE_OPEN,
489-
create_options, smb2_data,
490-
SMB2_OP_QUERY_INFO, NULL);
490+
create_options, ACL_NO_MODE,
491+
smb2_data, SMB2_OP_QUERY_INFO, NULL);
491492
}
492493
if (rc)
493494
goto out;
@@ -499,12 +500,14 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
499500
}
500501

501502
int
502-
smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
503+
smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
504+
struct cifs_tcon *tcon, const char *name,
503505
struct cifs_sb_info *cifs_sb)
504506
{
505507
return smb2_compound_op(xid, tcon, cifs_sb, name,
506508
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
507-
CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR, NULL);
509+
CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
510+
NULL);
508511
}
509512

510513
void
@@ -525,8 +528,8 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
525528
cifs_get_writable_path(tcon, name, &cfile);
526529
tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
527530
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
528-
CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO,
529-
cfile);
531+
CREATE_NOT_FILE, ACL_NO_MODE,
532+
&data, SMB2_OP_SET_INFO, cfile);
530533
if (tmprc == 0)
531534
cifs_i->cifsAttrs = dosattrs;
532535
}
@@ -536,7 +539,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
536539
struct cifs_sb_info *cifs_sb)
537540
{
538541
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
539-
CREATE_NOT_FILE,
542+
CREATE_NOT_FILE, ACL_NO_MODE,
540543
NULL, SMB2_OP_RMDIR, NULL);
541544
}
542545

@@ -546,7 +549,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
546549
{
547550
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
548551
CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
549-
NULL, SMB2_OP_DELETE, NULL);
552+
ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
550553
}
551554

552555
static int
@@ -564,7 +567,8 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
564567
goto smb2_rename_path;
565568
}
566569
rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
567-
FILE_OPEN, 0, smb2_to_name, command, cfile);
570+
FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
571+
command, cfile);
568572
smb2_rename_path:
569573
kfree(smb2_to_name);
570574
return rc;
@@ -601,8 +605,8 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
601605
__le64 eof = cpu_to_le64(size);
602606

603607
return smb2_compound_op(xid, tcon, cifs_sb, full_path,
604-
FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
605-
SMB2_OP_SET_EOF, NULL);
608+
FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
609+
&eof, SMB2_OP_SET_EOF, NULL);
606610
}
607611

608612
int
@@ -623,8 +627,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
623627
return PTR_ERR(tlink);
624628

625629
rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path,
626-
FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
627-
SMB2_OP_SET_INFO, NULL);
630+
FILE_WRITE_ATTRIBUTES, FILE_OPEN,
631+
0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, NULL);
628632
cifs_put_tlink(tlink);
629633
return rc;
630634
}

fs/cifs/smb2ops.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
751751
goto oshr_exit;
752752
}
753753

754+
atomic_inc(&tcon->num_remote_opens);
755+
754756
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
755757
oparms.fid->persistent_fid = o_rsp->PersistentFileId;
756758
oparms.fid->volatile_fid = o_rsp->VolatileFileId;
@@ -1176,6 +1178,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
11761178

11771179
rc = compound_send_recv(xid, ses, flags, 3, rqst,
11781180
resp_buftype, rsp_iov);
1181+
/* no need to bump num_remote_opens because handle immediately closed */
11791182

11801183
sea_exit:
11811184
kfree(ea);
@@ -1518,6 +1521,8 @@ smb2_ioctl_query_info(const unsigned int xid,
15181521
resp_buftype, rsp_iov);
15191522
if (rc)
15201523
goto iqinf_exit;
1524+
1525+
/* No need to bump num_remote_opens since handle immediately closed */
15211526
if (qi.flags & PASSTHRU_FSCTL) {
15221527
pqi = (struct smb_query_info __user *)arg;
15231528
io_rsp = (struct smb2_ioctl_rsp *)rsp_iov[1].iov_base;
@@ -3328,6 +3333,11 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
33283333
if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
33293334
return;
33303335

3336+
/* Check if the server granted an oplock rather than a lease */
3337+
if (oplock & SMB2_OPLOCK_LEVEL_EXCLUSIVE)
3338+
return smb2_set_oplock_level(cinode, oplock, epoch,
3339+
purge_cache);
3340+
33313341
if (oplock & SMB2_LEASE_READ_CACHING_HE) {
33323342
new_oplock |= CIFS_CACHE_READ_FLG;
33333343
strcat(message, "R");

0 commit comments

Comments
 (0)