Skip to content

Commit 7952058

Browse files
sprasad-microsoftSteve French
authored andcommitted
cifs: update the same create_guid on replay
File open requests made to the server contain a CreateGuid, which is used by the server to identify the open request. If the same request needs to be replayed, it needs to be sent with the same CreateGuid in the durable handle v2 context. Without doing so, we could end up leaking handles on the server when: 1. multichannel is used AND 2. connection goes down, but not for all channels This is because the replayed open request would have a new CreateGuid and the server will treat this as a new request and open a new handle. This change fixes this by reusing the existing create_guid stored in the cached fid struct. REF: MS-SMB2 4.9 Replay Create Request on an Alternate Channel Fixes: 4f1fffa ("cifs: commands that are retried should have replay flag set") Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent cffe487 commit 7952058

File tree

4 files changed

+14
-2
lines changed

4 files changed

+14
-2
lines changed

fs/smb/client/cached_dir.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
242242
.desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES,
243243
.disposition = FILE_OPEN,
244244
.fid = pfid,
245+
.replay = !!(retries),
245246
};
246247

247248
rc = SMB2_open_init(tcon, server,

fs/smb/client/cifsglob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,7 @@ struct cifs_open_parms {
13781378
struct cifs_fid *fid;
13791379
umode_t mode;
13801380
bool reconnect:1;
1381+
bool replay:1; /* indicates that this open is for a replay */
13811382
};
13821383

13831384
struct cifs_fid {

fs/smb/client/smb2ops.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
12041204
.disposition = FILE_OPEN,
12051205
.create_options = cifs_create_options(cifs_sb, 0),
12061206
.fid = &fid,
1207+
.replay = !!(retries),
12071208
};
12081209

12091210
rc = SMB2_open_init(tcon, server,
@@ -1569,6 +1570,7 @@ smb2_ioctl_query_info(const unsigned int xid,
15691570
.disposition = FILE_OPEN,
15701571
.create_options = cifs_create_options(cifs_sb, create_options),
15711572
.fid = &fid,
1573+
.replay = !!(retries),
15721574
};
15731575

15741576
if (qi.flags & PASSTHRU_FSCTL) {
@@ -2295,6 +2297,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
22952297
.disposition = FILE_OPEN,
22962298
.create_options = cifs_create_options(cifs_sb, 0),
22972299
.fid = fid,
2300+
.replay = !!(retries),
22982301
};
22992302

23002303
rc = SMB2_open_init(tcon, server,
@@ -2681,6 +2684,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
26812684
.disposition = FILE_OPEN,
26822685
.create_options = cifs_create_options(cifs_sb, 0),
26832686
.fid = &fid,
2687+
.replay = !!(retries),
26842688
};
26852689

26862690
rc = SMB2_open_init(tcon, server,

fs/smb/client/smb2pdu.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,8 +2404,13 @@ create_durable_v2_buf(struct cifs_open_parms *oparms)
24042404
*/
24052405
buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout);
24062406
buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
2407-
generate_random_uuid(buf->dcontext.CreateGuid);
2408-
memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
2407+
2408+
/* for replay, we should not overwrite the existing create guid */
2409+
if (!oparms->replay) {
2410+
generate_random_uuid(buf->dcontext.CreateGuid);
2411+
memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
2412+
} else
2413+
memcpy(buf->dcontext.CreateGuid, pfid->create_guid, 16);
24092414

24102415
/* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
24112416
buf->Name[0] = 'D';
@@ -3142,6 +3147,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
31423147
/* reinitialize for possible replay */
31433148
flags = 0;
31443149
server = cifs_pick_channel(ses);
3150+
oparms->replay = !!(retries);
31453151

31463152
cifs_dbg(FYI, "create/open\n");
31473153
if (!ses || !server)

0 commit comments

Comments
 (0)