@@ -1162,6 +1162,16 @@ cifs_destroy_mids(void)
kmem_cache_destroy(cifs_mid_cachep);
}
+static void init_guids(void)
+{
+ /* We do not sent a client GUID for SMB2.02 dialect */
+ memset(&smb20_values.client_guid, 0, SMB2_CLIENT_GUID_SIZE);
+
+ get_random_bytes(&smb21_values.client_guid, SMB2_CLIENT_GUID_SIZE);
+ get_random_bytes(&smb30_values.client_guid, SMB2_CLIENT_GUID_SIZE);
+ get_random_bytes(&smb302_values.client_guid, SMB2_CLIENT_GUID_SIZE);
+}
+
static int __init
init_cifs(void)
{
@@ -1196,6 +1206,11 @@ init_cifs(void)
spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);
+
+#ifdef CONFIG_CIFS_SMB2
+ init_guids();
+#endif
+
if (cifs_max_pending < 2) {
cifs_max_pending = 2;
cifs_dbg(FYI, "cifs_max_pending set to min of 2\n");
@@ -429,6 +429,7 @@ struct smb_version_values {
__u16 signing_enabled;
__u16 signing_required;
size_t create_lease_size;
+ __u8 client_guid[SMB2_CLIENT_GUID_SIZE];
};
#define HEADER_SIZE(server) (server->vals->header_size)
@@ -564,7 +565,6 @@ struct TCP_Server_Info {
int echo_credits; /* echo reserved slots */
int oplock_credits; /* oplock break reserved slots */
bool echoes:1; /* enable echoes */
- __u8 client_guid[SMB2_CLIENT_GUID_SIZE]; /* Client GUID */
#endif
u16 dialect; /* dialect index that server chose */
bool oplocks:1; /* enable oplocks */
@@ -2144,9 +2144,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
sizeof(tcp_ses->srcaddr));
memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
sizeof(tcp_ses->dstaddr));
-#ifdef CONFIG_CIFS_SMB2
- get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
-#endif
/*
* at this point we are the only ones with the pointer
* to the struct since the kernel thread not created yet
@@ -360,12 +360,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities);
- /* ClientGUID must be zero for SMB2.02 dialect */
- if (ses->server->vals->protocol_id == SMB20_PROT_ID)
- memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE);
- else
- memcpy(req->ClientGUID, server->client_guid,
- SMB2_CLIENT_GUID_SIZE);
+ memcpy(req->ClientGUID, &server->vals->client_guid,
+ SMB2_CLIENT_GUID_SIZE);
iov[0].iov_base = (char *)req;
/* 4 for rfc1002 length field */
@@ -468,7 +464,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
vneg_inbuf.Capabilities =
cpu_to_le32(tcon->ses->server->vals->req_capabilities);
- memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid,
+ memcpy(vneg_inbuf.Guid, &tcon->ses->server->vals->client_guid,
SMB2_CLIENT_GUID_SIZE);
if (tcon->ses->sign)
Commit 39552ea8120a699dbd0360848c4d949f9f0e6deb changes guid on per connection basis. This can cause problems in the future when making multichannel associations. The problem is described by Tom Talpey at https://www.mail-archive.com/linux-cifs@vger.kernel.org/msg09396.html We try and work around this problem by assigning a client guid for each smb2 dialect and use these GUIDs with their corresponding dialects. Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> --- fs/cifs/cifsfs.c | 15 +++++++++++++++ fs/cifs/cifsglob.h | 2 +- fs/cifs/connect.c | 3 --- fs/cifs/smb2pdu.c | 10 +++------- 4 files changed, 19 insertions(+), 11 deletions(-)