Skip to content

Commit 84c597f

Browse files
Paulo Alcantaragregkh
authored andcommitted
smb: client: fix potential broken compound request
[ Upstream commit 6914d28 ] Now that smb2_compound_op() can accept up to 5 commands in a single compound request, set the appropriate NextCommand and related flags to all subsequent commands as well as handling the case where a valid @CFILE is passed and therefore skipping create and close requests in the compound chain. This fix a potential broken compound request that could be sent from smb2_get_reparse_inode() if the client found a valid open file (@CFILE) prior to calling smb2_compound_op(). Signed-off-by: Paulo Alcantara <[email protected]> Signed-off-by: Steve French <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent db0f1c0 commit 84c597f

File tree

1 file changed

+63
-43
lines changed

1 file changed

+63
-43
lines changed

fs/smb/client/smb2inode.c

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,13 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
223223
SMB2_O_INFO_FILE, 0,
224224
sizeof(struct smb2_file_all_info) +
225225
PATH_MAX * 2, 0, NULL);
226-
if (!rc) {
227-
smb2_set_next_command(tcon, &rqst[num_rqst]);
228-
smb2_set_related(&rqst[num_rqst]);
229-
}
230226
}
231-
232-
if (rc)
227+
if (!rc && (!cfile || num_rqst > 1)) {
228+
smb2_set_next_command(tcon, &rqst[num_rqst]);
229+
smb2_set_related(&rqst[num_rqst]);
230+
} else if (rc) {
233231
goto finished;
232+
}
234233
num_rqst++;
235234
trace_smb3_query_info_compound_enter(xid, ses->Suid,
236235
tcon->tid, full_path);
@@ -260,14 +259,13 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
260259
sizeof(struct smb311_posix_qinfo *) +
261260
(PATH_MAX * 2) +
262261
(sizeof(struct cifs_sid) * 2), 0, NULL);
263-
if (!rc) {
264-
smb2_set_next_command(tcon, &rqst[num_rqst]);
265-
smb2_set_related(&rqst[num_rqst]);
266-
}
267262
}
268-
269-
if (rc)
263+
if (!rc && (!cfile || num_rqst > 1)) {
264+
smb2_set_next_command(tcon, &rqst[num_rqst]);
265+
smb2_set_related(&rqst[num_rqst]);
266+
} else if (rc) {
270267
goto finished;
268+
}
271269
num_rqst++;
272270
trace_smb3_posix_query_info_compound_enter(xid, ses->Suid,
273271
tcon->tid, full_path);
@@ -325,13 +323,13 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
325323
FILE_END_OF_FILE_INFORMATION,
326324
SMB2_O_INFO_FILE, 0,
327325
data, size);
328-
if (!rc) {
329-
smb2_set_next_command(tcon, &rqst[num_rqst]);
330-
smb2_set_related(&rqst[num_rqst]);
331-
}
332326
}
333-
if (rc)
327+
if (!rc && (!cfile || num_rqst > 1)) {
328+
smb2_set_next_command(tcon, &rqst[num_rqst]);
329+
smb2_set_related(&rqst[num_rqst]);
330+
} else if (rc) {
334331
goto finished;
332+
}
335333
num_rqst++;
336334
trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
337335
break;
@@ -356,14 +354,13 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
356354
COMPOUND_FID, current->tgid,
357355
FILE_BASIC_INFORMATION,
358356
SMB2_O_INFO_FILE, 0, data, size);
359-
if (!rc) {
360-
smb2_set_next_command(tcon, &rqst[num_rqst]);
361-
smb2_set_related(&rqst[num_rqst]);
362-
}
363357
}
364-
365-
if (rc)
358+
if (!rc && (!cfile || num_rqst > 1)) {
359+
smb2_set_next_command(tcon, &rqst[num_rqst]);
360+
smb2_set_related(&rqst[num_rqst]);
361+
} else if (rc) {
366362
goto finished;
363+
}
367364
num_rqst++;
368365
trace_smb3_set_info_compound_enter(xid, ses->Suid,
369366
tcon->tid, full_path);
@@ -397,13 +394,13 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
397394
COMPOUND_FID, COMPOUND_FID,
398395
current->tgid, FILE_RENAME_INFORMATION,
399396
SMB2_O_INFO_FILE, 0, data, size);
400-
if (!rc) {
401-
smb2_set_next_command(tcon, &rqst[num_rqst]);
402-
smb2_set_related(&rqst[num_rqst]);
403-
}
404397
}
405-
if (rc)
398+
if (!rc && (!cfile || num_rqst > 1)) {
399+
smb2_set_next_command(tcon, &rqst[num_rqst]);
400+
smb2_set_related(&rqst[num_rqst]);
401+
} else if (rc) {
406402
goto finished;
403+
}
407404
num_rqst++;
408405
trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path);
409406
break;
@@ -438,30 +435,53 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
438435
rqst[num_rqst].rq_iov = vars->io_iov;
439436
rqst[num_rqst].rq_nvec = ARRAY_SIZE(vars->io_iov);
440437

441-
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
442-
COMPOUND_FID, COMPOUND_FID,
443-
FSCTL_SET_REPARSE_POINT,
444-
in_iov[i].iov_base,
445-
in_iov[i].iov_len, 0);
446-
if (rc)
438+
if (cfile) {
439+
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
440+
cfile->fid.persistent_fid,
441+
cfile->fid.volatile_fid,
442+
FSCTL_SET_REPARSE_POINT,
443+
in_iov[i].iov_base,
444+
in_iov[i].iov_len, 0);
445+
} else {
446+
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
447+
COMPOUND_FID, COMPOUND_FID,
448+
FSCTL_SET_REPARSE_POINT,
449+
in_iov[i].iov_base,
450+
in_iov[i].iov_len, 0);
451+
}
452+
if (!rc && (!cfile || num_rqst > 1)) {
453+
smb2_set_next_command(tcon, &rqst[num_rqst]);
454+
smb2_set_related(&rqst[num_rqst]);
455+
} else if (rc) {
447456
goto finished;
448-
smb2_set_next_command(tcon, &rqst[num_rqst]);
449-
smb2_set_related(&rqst[num_rqst++]);
457+
}
458+
num_rqst++;
450459
trace_smb3_set_reparse_compound_enter(xid, ses->Suid,
451460
tcon->tid, full_path);
452461
break;
453462
case SMB2_OP_GET_REPARSE:
454463
rqst[num_rqst].rq_iov = vars->io_iov;
455464
rqst[num_rqst].rq_nvec = ARRAY_SIZE(vars->io_iov);
456465

457-
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
458-
COMPOUND_FID, COMPOUND_FID,
459-
FSCTL_GET_REPARSE_POINT,
460-
NULL, 0, CIFSMaxBufSize);
461-
if (rc)
466+
if (cfile) {
467+
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
468+
cfile->fid.persistent_fid,
469+
cfile->fid.volatile_fid,
470+
FSCTL_GET_REPARSE_POINT,
471+
NULL, 0, CIFSMaxBufSize);
472+
} else {
473+
rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst],
474+
COMPOUND_FID, COMPOUND_FID,
475+
FSCTL_GET_REPARSE_POINT,
476+
NULL, 0, CIFSMaxBufSize);
477+
}
478+
if (!rc && (!cfile || num_rqst > 1)) {
479+
smb2_set_next_command(tcon, &rqst[num_rqst]);
480+
smb2_set_related(&rqst[num_rqst]);
481+
} else if (rc) {
462482
goto finished;
463-
smb2_set_next_command(tcon, &rqst[num_rqst]);
464-
smb2_set_related(&rqst[num_rqst++]);
483+
}
484+
num_rqst++;
465485
trace_smb3_get_reparse_compound_enter(xid, ses->Suid,
466486
tcon->tid, full_path);
467487
break;

0 commit comments

Comments
 (0)