5 cifs/smb3 fixes, 2 for stable, includes an important fix for encryption and an ACL fix, as well as a fix for possible reflink data corruption
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmBfx9sACgkQiiy9cAdy T1F/igv8DsHxOJLw9kc5pBrbmUEgsUpQbdRMESqEROyqKte80jga2P3wsvJQYqQY JwHPxh477eiRSpSkEWSFDMmELsVtoQIYv3aqgPe79668eCd97mHRM2ItSV++5x9M iJ0N8GuiVARSyKmndrZ9gvbPoJb4TKkPX6X44pDSgAkgskvTTFKTywZaY5IEiqKe 9zBWghZbNnWhtYG+2On2M2tzy8/Fo8aveLxhFhJstZ0IP6Px+Rg9GMdzRAfDJqK+ QQMwcqmRKjVo4/Z6yji/s9OI1+eQyIAKLa6cyB0Yd+AqnvDYv1dagkRAjRCHl/Ri 28loxGatXeXjXJGYU58EjNkKdoBUh09idJJolcMGwPSteL2j1DQDV9utbZLhAWPq yNugiIkzbQj3Z55UQ3n3u79pztK31GZ2TOcwJbIqQs3tctJ5aqUIWjQibLVpaNBR 7C5Yug9aC5gpr3LPIUD3AGZIUAenCzsVN5Y9br4SPx0/zHmbynyyF27w14shX8O/ 3uQr6xhl =NxLV -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
81b1d39fd3
|
@ -1130,8 +1130,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
|
|||
}
|
||||
|
||||
/* If it's any one of the ACE we're replacing, skip! */
|
||||
if (!mode_from_sid &&
|
||||
((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
|
||||
if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
|
||||
(compare_sids(&pntace->sid, pownersid) == 0) ||
|
||||
(compare_sids(&pntace->sid, pgrpsid) == 0) ||
|
||||
(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
|
||||
|
|
|
@ -919,8 +919,8 @@ struct cifs_ses {
|
|||
bool binding:1; /* are we binding the session? */
|
||||
__u16 session_flags;
|
||||
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
|
||||
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
|
||||
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
|
||||
__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
|
||||
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
|
||||
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
|
||||
|
||||
__u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
|
||||
|
|
|
@ -147,6 +147,11 @@
|
|||
*/
|
||||
#define SMB3_SIGN_KEY_SIZE (16)
|
||||
|
||||
/*
|
||||
* Size of the smb3 encryption/decryption keys
|
||||
*/
|
||||
#define SMB3_ENC_DEC_KEY_SIZE (32)
|
||||
|
||||
#define CIFS_CLIENT_CHALLENGE_SIZE (8)
|
||||
#define CIFS_SERVER_CHALLENGE_SIZE (8)
|
||||
#define CIFS_HMAC_MD5_HASH_SIZE (16)
|
||||
|
|
|
@ -165,6 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
|
|||
goto posix_open_ret;
|
||||
}
|
||||
} else {
|
||||
cifs_revalidate_mapping(*pinode);
|
||||
cifs_fattr_to_inode(*pinode, &fattr);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#define SMB2_HMACSHA256_SIZE (32)
|
||||
#define SMB2_CMACAES_SIZE (16)
|
||||
#define SMB3_SIGNKEY_SIZE (16)
|
||||
#define SMB3_GCM128_CRYPTKEY_SIZE (16)
|
||||
#define SMB3_GCM256_CRYPTKEY_SIZE (32)
|
||||
|
||||
/* Maximum buffer size value we can send with 1 credit */
|
||||
|
|
|
@ -754,8 +754,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
|||
}
|
||||
}
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
|
||||
return false;
|
||||
cifs_dbg(FYI, "No file id matched, oplock break ignored\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -2038,6 +2038,7 @@ smb2_duplicate_extents(const unsigned int xid,
|
|||
{
|
||||
int rc;
|
||||
unsigned int ret_data_len;
|
||||
struct inode *inode;
|
||||
struct duplicate_extents_to_file dup_ext_buf;
|
||||
struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
|
||||
|
||||
|
@ -2054,10 +2055,21 @@ smb2_duplicate_extents(const unsigned int xid,
|
|||
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
|
||||
src_off, dest_off, len);
|
||||
|
||||
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
|
||||
if (rc)
|
||||
goto duplicate_extents_out;
|
||||
inode = d_inode(trgtfile->dentry);
|
||||
if (inode->i_size < dest_off + len) {
|
||||
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
|
||||
if (rc)
|
||||
goto duplicate_extents_out;
|
||||
|
||||
/*
|
||||
* Although also could set plausible allocation size (i_blocks)
|
||||
* here in addition to setting the file size, in reflink
|
||||
* it is likely that the target file is sparse. Its allocation
|
||||
* size will be queried on next revalidate, but it is important
|
||||
* to make sure that file's cached size is updated immediately
|
||||
*/
|
||||
cifs_setsize(inode, dest_off + len);
|
||||
}
|
||||
rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
|
||||
trgtfile->fid.volatile_fid,
|
||||
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)
|
|||
if (ses->Suid == ses_id) {
|
||||
ses_enc_key = enc ? ses->smb3encryptionkey :
|
||||
ses->smb3decryptionkey;
|
||||
memcpy(key, ses_enc_key, SMB3_SIGN_KEY_SIZE);
|
||||
memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4185,7 +4197,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
|||
int rc = 0;
|
||||
struct scatterlist *sg;
|
||||
u8 sign[SMB2_SIGNATURE_SIZE] = {};
|
||||
u8 key[SMB3_SIGN_KEY_SIZE];
|
||||
u8 key[SMB3_ENC_DEC_KEY_SIZE];
|
||||
struct aead_request *req;
|
||||
char *iv;
|
||||
unsigned int iv_len;
|
||||
|
@ -4209,10 +4221,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
|||
tfm = enc ? server->secmech.ccmaesencrypt :
|
||||
server->secmech.ccmaesdecrypt;
|
||||
|
||||
if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
|
||||
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
|
||||
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
|
||||
rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
|
||||
else
|
||||
rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE);
|
||||
rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
|
||||
|
||||
if (rc) {
|
||||
cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc);
|
||||
|
|
|
@ -298,7 +298,8 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
|
|||
{
|
||||
unsigned char zero = 0x0;
|
||||
__u8 i[4] = {0, 0, 0, 1};
|
||||
__u8 L[4] = {0, 0, 0, 128};
|
||||
__u8 L128[4] = {0, 0, 0, 128};
|
||||
__u8 L256[4] = {0, 0, 1, 0};
|
||||
int rc = 0;
|
||||
unsigned char prfhash[SMB2_HMACSHA256_SIZE];
|
||||
unsigned char *hashptr = prfhash;
|
||||
|
@ -354,8 +355,14 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
|
|||
goto smb3signkey_ret;
|
||||
}
|
||||
|
||||
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
|
||||
L, 4);
|
||||
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
|
||||
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
|
||||
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
|
||||
L256, 4);
|
||||
} else {
|
||||
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
|
||||
L128, 4);
|
||||
}
|
||||
if (rc) {
|
||||
cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
|
||||
goto smb3signkey_ret;
|
||||
|
@ -390,6 +397,9 @@ generate_smb3signingkey(struct cifs_ses *ses,
|
|||
const struct derivation_triplet *ptriplet)
|
||||
{
|
||||
int rc;
|
||||
#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
|
||||
struct TCP_Server_Info *server = ses->server;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All channels use the same encryption/decryption keys but
|
||||
|
@ -422,11 +432,11 @@ generate_smb3signingkey(struct cifs_ses *ses,
|
|||
rc = generate_key(ses, ptriplet->encryption.label,
|
||||
ptriplet->encryption.context,
|
||||
ses->smb3encryptionkey,
|
||||
SMB3_SIGN_KEY_SIZE);
|
||||
SMB3_ENC_DEC_KEY_SIZE);
|
||||
rc = generate_key(ses, ptriplet->decryption.label,
|
||||
ptriplet->decryption.context,
|
||||
ses->smb3decryptionkey,
|
||||
SMB3_SIGN_KEY_SIZE);
|
||||
SMB3_ENC_DEC_KEY_SIZE);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -442,14 +452,23 @@ generate_smb3signingkey(struct cifs_ses *ses,
|
|||
*/
|
||||
cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
|
||||
&ses->Suid);
|
||||
cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
|
||||
cifs_dbg(VFS, "Session Key %*ph\n",
|
||||
SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
|
||||
cifs_dbg(VFS, "Signing Key %*ph\n",
|
||||
SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
|
||||
cifs_dbg(VFS, "ServerIn Key %*ph\n",
|
||||
SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
|
||||
cifs_dbg(VFS, "ServerOut Key %*ph\n",
|
||||
SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
|
||||
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
|
||||
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
|
||||
cifs_dbg(VFS, "ServerIn Key %*ph\n",
|
||||
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
|
||||
cifs_dbg(VFS, "ServerOut Key %*ph\n",
|
||||
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
|
||||
} else {
|
||||
cifs_dbg(VFS, "ServerIn Key %*ph\n",
|
||||
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
|
||||
cifs_dbg(VFS, "ServerOut Key %*ph\n",
|
||||
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue