Skip to content

Commit 33640d7

Browse files
committed
Merge tag '5.0-rc4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb3 fixes from Steve French: "SMB3 fixes, some from this week's SMB3 test evemt, 5 for stable and a particularly important one for queryxattr (see xfstests 70 and 117)" * tag '5.0-rc4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: update internal module version number CIFS: fix use-after-free of the lease keys CIFS: Do not consider -ENODATA as stat failure for reads CIFS: Do not count -ENODATA as failure for query directory CIFS: Fix trace command logging for SMB2 reads and writes CIFS: Fix possible oops and memory leaks in async IO cifs: limit amount of data we request for xattrs to CIFSMaxBufSize cifs: fix computation for MAX_SMB2_HDR_SIZE
2 parents b7bd29b + b9b9378 commit 33640d7

File tree

5 files changed

+61
-29
lines changed

5 files changed

+61
-29
lines changed

fs/cifs/cifsfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
150150
extern const struct export_operations cifs_export_ops;
151151
#endif /* CONFIG_CIFS_NFSD_EXPORT */
152152

153-
#define CIFS_VERSION "2.16"
153+
#define CIFS_VERSION "2.17"
154154
#endif /* _CIFSFS_H */

fs/cifs/file.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,6 +2696,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
26962696

26972697
rc = cifs_write_allocate_pages(wdata->pages, nr_pages);
26982698
if (rc) {
2699+
kvfree(wdata->pages);
26992700
kfree(wdata);
27002701
add_credits_and_wake_if(server, credits, 0);
27012702
break;
@@ -2707,6 +2708,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
27072708
if (rc) {
27082709
for (i = 0; i < nr_pages; i++)
27092710
put_page(wdata->pages[i]);
2711+
kvfree(wdata->pages);
27102712
kfree(wdata);
27112713
add_credits_and_wake_if(server, credits, 0);
27122714
break;
@@ -3386,8 +3388,12 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
33863388
}
33873389

33883390
rc = cifs_read_allocate_pages(rdata, npages);
3389-
if (rc)
3390-
goto error;
3391+
if (rc) {
3392+
kvfree(rdata->pages);
3393+
kfree(rdata);
3394+
add_credits_and_wake_if(server, credits, 0);
3395+
break;
3396+
}
33913397

33923398
rdata->tailsz = PAGE_SIZE;
33933399
}
@@ -3407,7 +3413,6 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
34073413
if (!rdata->cfile->invalidHandle ||
34083414
!(rc = cifs_reopen_file(rdata->cfile, true)))
34093415
rc = server->ops->async_readv(rdata);
3410-
error:
34113416
if (rc) {
34123417
add_credits_and_wake_if(server, rdata->credits, 0);
34133418
kref_put(&rdata->refcount,

fs/cifs/smb2ops.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,9 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
866866
FILE_READ_EA,
867867
FILE_FULL_EA_INFORMATION,
868868
SMB2_O_INFO_FILE,
869-
SMB2_MAX_EA_BUF,
869+
CIFSMaxBufSize -
870+
MAX_SMB2_CREATE_RESPONSE_SIZE -
871+
MAX_SMB2_CLOSE_RESPONSE_SIZE,
870872
&rsp_iov, &buftype, cifs_sb);
871873
if (rc) {
872874
/*

fs/cifs/smb2pdu.c

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3241,8 +3241,17 @@ smb2_readv_callback(struct mid_q_entry *mid)
32413241
rdata->mr = NULL;
32423242
}
32433243
#endif
3244-
if (rdata->result)
3244+
if (rdata->result && rdata->result != -ENODATA) {
32453245
cifs_stats_fail_inc(tcon, SMB2_READ_HE);
3246+
trace_smb3_read_err(0 /* xid */,
3247+
rdata->cfile->fid.persistent_fid,
3248+
tcon->tid, tcon->ses->Suid, rdata->offset,
3249+
rdata->bytes, rdata->result);
3250+
} else
3251+
trace_smb3_read_done(0 /* xid */,
3252+
rdata->cfile->fid.persistent_fid,
3253+
tcon->tid, tcon->ses->Suid,
3254+
rdata->offset, rdata->got_bytes);
32463255

32473256
queue_work(cifsiod_wq, &rdata->work);
32483257
DeleteMidQEntry(mid);
@@ -3317,13 +3326,11 @@ smb2_async_readv(struct cifs_readdata *rdata)
33173326
if (rc) {
33183327
kref_put(&rdata->refcount, cifs_readdata_release);
33193328
cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
3320-
trace_smb3_read_err(rc, 0 /* xid */, io_parms.persistent_fid,
3321-
io_parms.tcon->tid, io_parms.tcon->ses->Suid,
3322-
io_parms.offset, io_parms.length);
3323-
} else
3324-
trace_smb3_read_done(0 /* xid */, io_parms.persistent_fid,
3325-
io_parms.tcon->tid, io_parms.tcon->ses->Suid,
3326-
io_parms.offset, io_parms.length);
3329+
trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
3330+
io_parms.tcon->tid,
3331+
io_parms.tcon->ses->Suid,
3332+
io_parms.offset, io_parms.length, rc);
3333+
}
33273334

33283335
cifs_small_buf_release(buf);
33293336
return rc;
@@ -3367,10 +3374,11 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
33673374
if (rc != -ENODATA) {
33683375
cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
33693376
cifs_dbg(VFS, "Send error in read = %d\n", rc);
3377+
trace_smb3_read_err(xid, req->PersistentFileId,
3378+
io_parms->tcon->tid, ses->Suid,
3379+
io_parms->offset, io_parms->length,
3380+
rc);
33703381
}
3371-
trace_smb3_read_err(rc, xid, req->PersistentFileId,
3372-
io_parms->tcon->tid, ses->Suid,
3373-
io_parms->offset, io_parms->length);
33743382
free_rsp_buf(resp_buftype, rsp_iov.iov_base);
33753383
return rc == -ENODATA ? 0 : rc;
33763384
} else
@@ -3459,8 +3467,17 @@ smb2_writev_callback(struct mid_q_entry *mid)
34593467
wdata->mr = NULL;
34603468
}
34613469
#endif
3462-
if (wdata->result)
3470+
if (wdata->result) {
34633471
cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
3472+
trace_smb3_write_err(0 /* no xid */,
3473+
wdata->cfile->fid.persistent_fid,
3474+
tcon->tid, tcon->ses->Suid, wdata->offset,
3475+
wdata->bytes, wdata->result);
3476+
} else
3477+
trace_smb3_write_done(0 /* no xid */,
3478+
wdata->cfile->fid.persistent_fid,
3479+
tcon->tid, tcon->ses->Suid,
3480+
wdata->offset, wdata->bytes);
34643481

34653482
queue_work(cifsiod_wq, &wdata->work);
34663483
DeleteMidQEntry(mid);
@@ -3602,10 +3619,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
36023619
wdata->bytes, rc);
36033620
kref_put(&wdata->refcount, release);
36043621
cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
3605-
} else
3606-
trace_smb3_write_done(0 /* no xid */, req->PersistentFileId,
3607-
tcon->tid, tcon->ses->Suid, wdata->offset,
3608-
wdata->bytes);
3622+
}
36093623

36103624
async_writev_out:
36113625
cifs_small_buf_release(req);
@@ -3831,8 +3845,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
38313845
rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
38323846
srch_inf->endOfSearch = true;
38333847
rc = 0;
3834-
}
3835-
cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
3848+
} else
3849+
cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
38363850
goto qdir_exit;
38373851
}
38383852

@@ -4427,8 +4441,8 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
44274441
rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
44284442
cifs_small_buf_release(req);
44294443

4430-
please_key_low = (__u64 *)req->LeaseKey;
4431-
please_key_high = (__u64 *)(req->LeaseKey+8);
4444+
please_key_low = (__u64 *)lease_key;
4445+
please_key_high = (__u64 *)(lease_key+8);
44324446
if (rc) {
44334447
cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
44344448
trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid,

fs/cifs/smb2pdu.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@
8484

8585
#define NUMBER_OF_SMB2_COMMANDS 0x0013
8686

87-
/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */
88-
#define MAX_SMB2_HDR_SIZE 0x00b0
87+
/* 52 transform hdr + 64 hdr + 88 create rsp */
88+
#define SMB2_TRANSFORM_HEADER_SIZE 52
89+
#define MAX_SMB2_HDR_SIZE 204
8990

9091
#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
9192
#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
@@ -648,6 +649,13 @@ struct smb2_create_req {
648649
__u8 Buffer[0];
649650
} __packed;
650651

652+
/*
653+
* Maximum size of a SMB2_CREATE response is 64 (smb2 header) +
654+
* 88 (fixed part of create response) + 520 (path) + 150 (contexts) +
655+
* 2 bytes of padding.
656+
*/
657+
#define MAX_SMB2_CREATE_RESPONSE_SIZE 824
658+
651659
struct smb2_create_rsp {
652660
struct smb2_sync_hdr sync_hdr;
653661
__le16 StructureSize; /* Must be 89 */
@@ -996,6 +1004,11 @@ struct smb2_close_req {
9961004
__u64 VolatileFileId; /* opaque endianness */
9971005
} __packed;
9981006

1007+
/*
1008+
* Maximum size of a SMB2_CLOSE response is 64 (smb2 header) + 60 (data)
1009+
*/
1010+
#define MAX_SMB2_CLOSE_RESPONSE_SIZE 124
1011+
9991012
struct smb2_close_rsp {
10001013
struct smb2_sync_hdr sync_hdr;
10011014
__le16 StructureSize; /* 60 */
@@ -1398,8 +1411,6 @@ struct smb2_file_link_info { /* encoding of request for level 11 */
13981411
char FileName[0]; /* Name to be assigned to new link */
13991412
} __packed; /* level 11 Set */
14001413

1401-
#define SMB2_MAX_EA_BUF 65536
1402-
14031414
struct smb2_file_full_ea_info { /* encoding of response for level 15 */
14041415
__le32 next_entry_offset;
14051416
__u8 flags;

0 commit comments

Comments
 (0)