Skip to content

Commit 81b1d39

Browse files
committed
Merge tag '5.12-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Five cifs/smb3 fixes, two for stable. Includes an important fix for encryption and an ACL fix, as well as a fix for possible reflink data corruption" * tag '5.12-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6: smb3: fix cached file size problems in duplicate extents (reflink) cifs: Silently ignore unknown oplock break handle cifs: revalidate mapping when we open files for SMB1 POSIX cifs: Fix chmod with modefromsid when an older ACE already exists. cifs: Adjust key sizes and key generation routines for AES256 encryption
2 parents b44d1dd + cfc63fc commit 81b1d39

File tree

8 files changed

+60
-22
lines changed

8 files changed

+60
-22
lines changed

fs/cifs/cifsacl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,8 +1130,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
11301130
}
11311131

11321132
/* If it's any one of the ACE we're replacing, skip! */
1133-
if (!mode_from_sid &&
1134-
((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1133+
if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
11351134
(compare_sids(&pntace->sid, pownersid) == 0) ||
11361135
(compare_sids(&pntace->sid, pgrpsid) == 0) ||
11371136
(compare_sids(&pntace->sid, &sid_everyone) == 0) ||

fs/cifs/cifsglob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,8 @@ struct cifs_ses {
919919
bool binding:1; /* are we binding the session? */
920920
__u16 session_flags;
921921
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
922-
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
923-
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
922+
__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
923+
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
924924
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
925925

926926
__u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];

fs/cifs/cifspdu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@
147147
*/
148148
#define SMB3_SIGN_KEY_SIZE (16)
149149

150+
/*
151+
* Size of the smb3 encryption/decryption keys
152+
*/
153+
#define SMB3_ENC_DEC_KEY_SIZE (32)
154+
150155
#define CIFS_CLIENT_CHALLENGE_SIZE (8)
151156
#define CIFS_SERVER_CHALLENGE_SIZE (8)
152157
#define CIFS_HMAC_MD5_HASH_SIZE (16)

fs/cifs/file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
165165
goto posix_open_ret;
166166
}
167167
} else {
168+
cifs_revalidate_mapping(*pinode);
168169
cifs_fattr_to_inode(*pinode, &fattr);
169170
}
170171

fs/cifs/smb2glob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#define SMB2_HMACSHA256_SIZE (32)
5959
#define SMB2_CMACAES_SIZE (16)
6060
#define SMB3_SIGNKEY_SIZE (16)
61+
#define SMB3_GCM128_CRYPTKEY_SIZE (16)
6162
#define SMB3_GCM256_CRYPTKEY_SIZE (32)
6263

6364
/* Maximum buffer size value we can send with 1 credit */

fs/cifs/smb2misc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
754754
}
755755
}
756756
spin_unlock(&cifs_tcp_ses_lock);
757-
cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
758-
return false;
757+
cifs_dbg(FYI, "No file id matched, oplock break ignored\n");
758+
return true;
759759
}
760760

761761
void

fs/cifs/smb2ops.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,7 @@ smb2_duplicate_extents(const unsigned int xid,
20382038
{
20392039
int rc;
20402040
unsigned int ret_data_len;
2041+
struct inode *inode;
20412042
struct duplicate_extents_to_file dup_ext_buf;
20422043
struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
20432044

@@ -2054,10 +2055,21 @@ smb2_duplicate_extents(const unsigned int xid,
20542055
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
20552056
src_off, dest_off, len);
20562057

2057-
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
2058-
if (rc)
2059-
goto duplicate_extents_out;
2058+
inode = d_inode(trgtfile->dentry);
2059+
if (inode->i_size < dest_off + len) {
2060+
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
2061+
if (rc)
2062+
goto duplicate_extents_out;
20602063

2064+
/*
2065+
* Although also could set plausible allocation size (i_blocks)
2066+
* here in addition to setting the file size, in reflink
2067+
* it is likely that the target file is sparse. Its allocation
2068+
* size will be queried on next revalidate, but it is important
2069+
* to make sure that file's cached size is updated immediately
2070+
*/
2071+
cifs_setsize(inode, dest_off + len);
2072+
}
20612073
rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
20622074
trgtfile->fid.volatile_fid,
20632075
FSCTL_DUPLICATE_EXTENTS_TO_FILE,
@@ -4158,7 +4170,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
41584170
if (ses->Suid == ses_id) {
41594171
ses_enc_key = enc ? ses->smb3encryptionkey :
41604172
ses->smb3decryptionkey;
4161-
memcpy(key, ses_enc_key, SMB3_SIGN_KEY_SIZE);
4173+
memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
41624174
spin_unlock(&cifs_tcp_ses_lock);
41634175
return 0;
41644176
}
@@ -4185,7 +4197,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
41854197
int rc = 0;
41864198
struct scatterlist *sg;
41874199
u8 sign[SMB2_SIGNATURE_SIZE] = {};
4188-
u8 key[SMB3_SIGN_KEY_SIZE];
4200+
u8 key[SMB3_ENC_DEC_KEY_SIZE];
41894201
struct aead_request *req;
41904202
char *iv;
41914203
unsigned int iv_len;
@@ -4209,10 +4221,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
42094221
tfm = enc ? server->secmech.ccmaesencrypt :
42104222
server->secmech.ccmaesdecrypt;
42114223

4212-
if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
4224+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
4225+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
42134226
rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
42144227
else
4215-
rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE);
4228+
rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
42164229

42174230
if (rc) {
42184231
cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc);

fs/cifs/smb2transport.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
298298
{
299299
unsigned char zero = 0x0;
300300
__u8 i[4] = {0, 0, 0, 1};
301-
__u8 L[4] = {0, 0, 0, 128};
301+
__u8 L128[4] = {0, 0, 0, 128};
302+
__u8 L256[4] = {0, 0, 1, 0};
302303
int rc = 0;
303304
unsigned char prfhash[SMB2_HMACSHA256_SIZE];
304305
unsigned char *hashptr = prfhash;
@@ -354,8 +355,14 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
354355
goto smb3signkey_ret;
355356
}
356357

357-
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
358-
L, 4);
358+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
359+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
360+
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
361+
L256, 4);
362+
} else {
363+
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
364+
L128, 4);
365+
}
359366
if (rc) {
360367
cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
361368
goto smb3signkey_ret;
@@ -390,6 +397,9 @@ generate_smb3signingkey(struct cifs_ses *ses,
390397
const struct derivation_triplet *ptriplet)
391398
{
392399
int rc;
400+
#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
401+
struct TCP_Server_Info *server = ses->server;
402+
#endif
393403

394404
/*
395405
* All channels use the same encryption/decryption keys but
@@ -422,11 +432,11 @@ generate_smb3signingkey(struct cifs_ses *ses,
422432
rc = generate_key(ses, ptriplet->encryption.label,
423433
ptriplet->encryption.context,
424434
ses->smb3encryptionkey,
425-
SMB3_SIGN_KEY_SIZE);
435+
SMB3_ENC_DEC_KEY_SIZE);
426436
rc = generate_key(ses, ptriplet->decryption.label,
427437
ptriplet->decryption.context,
428438
ses->smb3decryptionkey,
429-
SMB3_SIGN_KEY_SIZE);
439+
SMB3_ENC_DEC_KEY_SIZE);
430440
if (rc)
431441
return rc;
432442
}
@@ -442,14 +452,23 @@ generate_smb3signingkey(struct cifs_ses *ses,
442452
*/
443453
cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
444454
&ses->Suid);
455+
cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
445456
cifs_dbg(VFS, "Session Key %*ph\n",
446457
SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
447458
cifs_dbg(VFS, "Signing Key %*ph\n",
448459
SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
449-
cifs_dbg(VFS, "ServerIn Key %*ph\n",
450-
SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
451-
cifs_dbg(VFS, "ServerOut Key %*ph\n",
452-
SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
460+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
461+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
462+
cifs_dbg(VFS, "ServerIn Key %*ph\n",
463+
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
464+
cifs_dbg(VFS, "ServerOut Key %*ph\n",
465+
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
466+
} else {
467+
cifs_dbg(VFS, "ServerIn Key %*ph\n",
468+
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
469+
cifs_dbg(VFS, "ServerOut Key %*ph\n",
470+
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
471+
}
453472
#endif
454473
return rc;
455474
}

0 commit comments

Comments
 (0)