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
Unified · Split
| @@ -150,5 +150,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); · 149 unmodified lines | ||
| 150 | 150 | extern const struct export_operations cifs_export_ops; |
| 151 | 151 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ |
| 152 | 152 | |
| 153 | −#define CIFS_VERSION "2.16" | |
| 153 | +#define CIFS_VERSION "2.17" | |
| 154 | 154 | #endif /* _CIFSFS_H */ |
| @@ -2696,6 +2696,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, · 2695 unmodified lines | ||
| 2696 | 2696 | |
| 2697 | 2697 | rc = cifs_write_allocate_pages(wdata->pages, nr_pages); |
| 2698 | 2698 | if (rc) { |
| 2699 | + kvfree(wdata->pages); | |
| 2699 | 2700 | kfree(wdata); |
| 2700 | 2701 | add_credits_and_wake_if(server, credits, 0); |
| 2701 | 2702 | break; |
| @@ -2707,6 +2708,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, · 5 unmodified lines | ||
| 2707 | 2708 | if (rc) { |
| 2708 | 2709 | for (i = 0; i < nr_pages; i++) |
| 2709 | 2710 | put_page(wdata->pages[i]); |
| 2711 | + kvfree(wdata->pages); | |
| 2710 | 2712 | kfree(wdata); |
| 2711 | 2713 | add_credits_and_wake_if(server, credits, 0); |
| 2712 | 2714 | break; |
| @@ -3386,8 +3388,12 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, · 673 unmodified lines | ||
| 3386 | 3388 | } |
| 3387 | 3389 | |
| 3388 | 3390 | 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 | + } | |
| 3391 | 3397 | |
| 3392 | 3398 | rdata->tailsz = PAGE_SIZE; |
| 3393 | 3399 | } |
| @@ -3407,7 +3413,6 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, · 13 unmodified lines | ||
| 3407 | 3413 | if (!rdata->cfile->invalidHandle || |
| 3408 | 3414 | !(rc = cifs_reopen_file(rdata->cfile, true))) |
| 3409 | 3415 | rc = server->ops->async_readv(rdata); |
| 3410 | −error: | |
| 3411 | 3416 | if (rc) { |
| 3412 | 3417 | add_credits_and_wake_if(server, rdata->credits, 0); |
| 3413 | 3418 | kref_put(&rdata->refcount, |
| @@ -866,7 +866,9 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, · 865 unmodified lines | ||
| 866 | 866 | FILE_READ_EA, |
| 867 | 867 | FILE_FULL_EA_INFORMATION, |
| 868 | 868 | SMB2_O_INFO_FILE, |
| 869 | − SMB2_MAX_EA_BUF, | |
| 869 | + CIFSMaxBufSize - | |
| 870 | + MAX_SMB2_CREATE_RESPONSE_SIZE - | |
| 871 | + MAX_SMB2_CLOSE_RESPONSE_SIZE, | |
| 870 | 872 | &rsp_iov, &buftype, cifs_sb); |
| 871 | 873 | if (rc) { |
| 872 | 874 | /* |
| @@ -3241,8 +3241,17 @@ smb2_readv_callback(struct mid_q_entry *mid) · 3240 unmodified lines | ||
| 3241 | 3241 | rdata->mr = NULL; |
| 3242 | 3242 | } |
| 3243 | 3243 | #endif |
| 3244 | − if (rdata->result) | |
| 3244 | + if (rdata->result && rdata->result != -ENODATA) { | |
| 3245 | 3245 | 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); | |
| 3246 | 3255 | |
| 3247 | 3256 | queue_work(cifsiod_wq, &rdata->work); |
| 3248 | 3257 | DeleteMidQEntry(mid); |
| @@ -3317,13 +3326,11 @@ smb2_async_readv(struct cifs_readdata *rdata) · 68 unmodified lines | ||
| 3317 | 3326 | if (rc) { |
| 3318 | 3327 | kref_put(&rdata->refcount, cifs_readdata_release); |
| 3319 | 3328 | 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 | + } | |
| 3327 | 3334 | |
| 3328 | 3335 | cifs_small_buf_release(buf); |
| 3329 | 3336 | return rc; |
| @@ -3367,10 +3374,11 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, · 37 unmodified lines | ||
| 3367 | 3374 | if (rc != -ENODATA) { |
| 3368 | 3375 | cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); |
| 3369 | 3376 | 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); | |
| 3370 | 3381 | } |
| 3371 | − trace_smb3_read_err(rc, xid, req->PersistentFileId, | |
| 3372 | − io_parms->tcon->tid, ses->Suid, | |
| 3373 | − io_parms->offset, io_parms->length); | |
| 3374 | 3382 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); |
| 3375 | 3383 | return rc == -ENODATA ? 0 : rc; |
| 3376 | 3384 | } else |
| @@ -3459,8 +3467,17 @@ smb2_writev_callback(struct mid_q_entry *mid) · 82 unmodified lines | ||
| 3459 | 3467 | wdata->mr = NULL; |
| 3460 | 3468 | } |
| 3461 | 3469 | #endif |
| 3462 | − if (wdata->result) | |
| 3470 | + if (wdata->result) { | |
| 3463 | 3471 | 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); | |
| 3464 | 3481 | |
| 3465 | 3482 | queue_work(cifsiod_wq, &wdata->work); |
| 3466 | 3483 | DeleteMidQEntry(mid); |
| @@ -3602,10 +3619,7 @@ smb2_async_writev(struct cifs_writedata *wdata, · 135 unmodified lines | ||
| 3602 | 3619 | wdata->bytes, rc); |
| 3603 | 3620 | kref_put(&wdata->refcount, release); |
| 3604 | 3621 | 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 | + } | |
| 3609 | 3623 | |
| 3610 | 3624 | async_writev_out: |
| 3611 | 3625 | cifs_small_buf_release(req); |
| @@ -3831,8 +3845,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, · 219 unmodified lines | ||
| 3831 | 3845 | rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { |
| 3832 | 3846 | srch_inf->endOfSearch = true; |
| 3833 | 3847 | 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); | |
| 3836 | 3850 | goto qdir_exit; |
| 3837 | 3851 | } |
| 3838 | 3852 | |
| @@ -4427,8 +4441,8 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, · 588 unmodified lines | ||
| 4427 | 4441 | rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); |
| 4428 | 4442 | cifs_small_buf_release(req); |
| 4429 | 4443 | |
| 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); | |
| 4432 | 4446 | if (rc) { |
| 4433 | 4447 | cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE); |
| 4434 | 4448 | trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid, |
| @@ -84,8 +84,9 @@ · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 |
| 86 | 86 | |
| 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 | |
| 89 | 90 | |
| 90 | 91 | #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) |
| 91 | 92 | #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) |
| @@ -648,6 +649,13 @@ struct smb2_create_req { · 556 unmodified lines | ||
| 648 | 649 | __u8 Buffer[0]; |
| 649 | 650 | } __packed; |
| 650 | 651 | |
| 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 | + | |
| 651 | 659 | struct smb2_create_rsp { |
| 652 | 660 | struct smb2_sync_hdr sync_hdr; |
| 653 | 661 | __le16 StructureSize; /* Must be 89 */ |
| @@ -996,6 +1004,11 @@ struct smb2_close_req { · 342 unmodified lines | ||
| 996 | 1004 | __u64 VolatileFileId; /* opaque endianness */ |
| 997 | 1005 | } __packed; |
| 998 | 1006 | |
| 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 | + | |
| 999 | 1012 | struct smb2_close_rsp { |
| 1000 | 1013 | struct smb2_sync_hdr sync_hdr; |
| 1001 | 1014 | __le16 StructureSize; /* 60 */ |
| @@ -1398,8 +1411,6 @@ struct smb2_file_link_info { /* encoding of request for level 11 */ · 396 unmodified lines | ||
| 1398 | 1411 | char FileName[0]; /* Name to be assigned to new link */ |
| 1399 | 1412 | } __packed; /* level 11 Set */ |
| 1400 | 1413 | |
| 1401 | −#define SMB2_MAX_EA_BUF 65536 | |
| 1402 | − | |
| 1403 | 1414 | struct smb2_file_full_ea_info { /* encoding of response for level 15 */ |
| 1404 | 1415 | __le32 next_entry_offset; |
| 1405 | 1416 | __u8 flags; |