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 | extern const struct export_operations cifs_export_ops; | 150 | extern const struct export_operations cifs_export_ops; |
| 151 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ | 151 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ |
| 152 | 152 | ||
| 153 | #define CIFS_VERSION "2.16" | 153 | #define CIFS_VERSION "2.17" |
| 154 | #endif /* _CIFSFS_H */ | 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 | rc = cifs_write_allocate_pages(wdata->pages, nr_pages); | 2697 | rc = cifs_write_allocate_pages(wdata->pages, nr_pages); |
| 2698 | if (rc) { | 2698 | if (rc) { |
| 2699 | kvfree(wdata->pages); | ||
| 2699 | kfree(wdata); | 2700 | kfree(wdata); |
| 2700 | add_credits_and_wake_if(server, credits, 0); | 2701 | add_credits_and_wake_if(server, credits, 0); |
| 2701 | break; | 2702 | break; |
| @@ -2707,6 +2708,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, · 5 unmodified lines | |||
| 2707 | if (rc) { | 2708 | if (rc) { |
| 2708 | for (i = 0; i < nr_pages; i++) | 2709 | for (i = 0; i < nr_pages; i++) |
| 2709 | put_page(wdata->pages[i]); | 2710 | put_page(wdata->pages[i]); |
| 2711 | kvfree(wdata->pages); | ||
| 2710 | kfree(wdata); | 2712 | kfree(wdata); |
| 2711 | add_credits_and_wake_if(server, credits, 0); | 2713 | add_credits_and_wake_if(server, credits, 0); |
| 2712 | break; | 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 | rc = cifs_read_allocate_pages(rdata, npages); | 3390 | rc = cifs_read_allocate_pages(rdata, npages); |
| 3389 | if (rc) | 3391 | if (rc) { |
| 3390 | goto error; | 3392 | kvfree(rdata->pages); |
| 3393 | kfree(rdata); | ||
| 3394 | add_credits_and_wake_if(server, credits, 0); | ||
| 3395 | break; | ||
| 3396 | } | ||
| 3391 | 3397 | ||
| 3392 | rdata->tailsz = PAGE_SIZE; | 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 | if (!rdata->cfile->invalidHandle || | 3413 | if (!rdata->cfile->invalidHandle || |
| 3408 | !(rc = cifs_reopen_file(rdata->cfile, true))) | 3414 | !(rc = cifs_reopen_file(rdata->cfile, true))) |
| 3409 | rc = server->ops->async_readv(rdata); | 3415 | rc = server->ops->async_readv(rdata); |
| 3410 | error: | ||
| 3411 | if (rc) { | 3416 | if (rc) { |
| 3412 | add_credits_and_wake_if(server, rdata->credits, 0); | 3417 | add_credits_and_wake_if(server, rdata->credits, 0); |
| 3413 | kref_put(&rdata->refcount, | 3418 | kref_put(&rdata->refcount, |
| @@ -866,7 +866,9 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, · 865 unmodified lines | |||
| 866 | FILE_READ_EA, | 866 | FILE_READ_EA, |
| 867 | FILE_FULL_EA_INFORMATION, | 867 | FILE_FULL_EA_INFORMATION, |
| 868 | SMB2_O_INFO_FILE, | 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 | &rsp_iov, &buftype, cifs_sb); | 872 | &rsp_iov, &buftype, cifs_sb); |
| 871 | if (rc) { | 873 | if (rc) { |
| 872 | /* | 874 | /* |
| @@ -3241,8 +3241,17 @@ smb2_readv_callback(struct mid_q_entry *mid) · 3240 unmodified lines | |||
| 3241 | rdata->mr = NULL; | 3241 | rdata->mr = NULL; |
| 3242 | } | 3242 | } |
| 3243 | #endif | 3243 | #endif |
| 3244 | if (rdata->result) | 3244 | if (rdata->result && rdata->result != -ENODATA) { |
| 3245 | cifs_stats_fail_inc(tcon, SMB2_READ_HE); | 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 | queue_work(cifsiod_wq, &rdata->work); | 3256 | queue_work(cifsiod_wq, &rdata->work); |
| 3248 | DeleteMidQEntry(mid); | 3257 | DeleteMidQEntry(mid); |
| @@ -3317,13 +3326,11 @@ smb2_async_readv(struct cifs_readdata *rdata) · 68 unmodified lines | |||
| 3317 | if (rc) { | 3326 | if (rc) { |
| 3318 | kref_put(&rdata->refcount, cifs_readdata_release); | 3327 | kref_put(&rdata->refcount, cifs_readdata_release); |
| 3319 | cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); | 3328 | cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); |
| 3320 | trace_smb3_read_err(rc, 0 /* xid */, io_parms.persistent_fid, | 3329 | trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid, |
| 3321 | io_parms.tcon->tid, io_parms.tcon->ses->Suid, | 3330 | io_parms.tcon->tid, |
| 3322 | io_parms.offset, io_parms.length); | 3331 | io_parms.tcon->ses->Suid, |
| 3323 | } else | 3332 | io_parms.offset, io_parms.length, rc); |
| 3324 | trace_smb3_read_done(0 /* xid */, io_parms.persistent_fid, | 3333 | } |
| 3325 | io_parms.tcon->tid, io_parms.tcon->ses->Suid, | ||
| 3326 | io_parms.offset, io_parms.length); | ||
| 3327 | 3334 | ||
| 3328 | cifs_small_buf_release(buf); | 3335 | cifs_small_buf_release(buf); |
| 3329 | return rc; | 3336 | return rc; |
| @@ -3367,10 +3374,11 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, · 37 unmodified lines | |||
| 3367 | if (rc != -ENODATA) { | 3374 | if (rc != -ENODATA) { |
| 3368 | cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); | 3375 | cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); |
| 3369 | cifs_dbg(VFS, "Send error in read = %d\n", rc); | 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 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); | 3382 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); |
| 3375 | return rc == -ENODATA ? 0 : rc; | 3383 | return rc == -ENODATA ? 0 : rc; |
| 3376 | } else | 3384 | } else |
| @@ -3459,8 +3467,17 @@ smb2_writev_callback(struct mid_q_entry *mid) · 82 unmodified lines | |||
| 3459 | wdata->mr = NULL; | 3467 | wdata->mr = NULL; |
| 3460 | } | 3468 | } |
| 3461 | #endif | 3469 | #endif |
| 3462 | if (wdata->result) | 3470 | if (wdata->result) { |
| 3463 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); | 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 | queue_work(cifsiod_wq, &wdata->work); | 3482 | queue_work(cifsiod_wq, &wdata->work); |
| 3466 | DeleteMidQEntry(mid); | 3483 | DeleteMidQEntry(mid); |
| @@ -3602,10 +3619,7 @@ smb2_async_writev(struct cifs_writedata *wdata, · 135 unmodified lines | |||
| 3602 | wdata->bytes, rc); | 3619 | wdata->bytes, rc); |
| 3603 | kref_put(&wdata->refcount, release); | 3620 | kref_put(&wdata->refcount, release); |
| 3604 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); | 3621 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); |
| 3605 | } else | 3622 | } |
| 3606 | trace_smb3_write_done(0 /* no xid */, req->PersistentFileId, | ||
| 3607 | tcon->tid, tcon->ses->Suid, wdata->offset, | ||
| 3608 | wdata->bytes); | ||
| 3609 | 3623 | ||
| 3610 | async_writev_out: | 3624 | async_writev_out: |
| 3611 | cifs_small_buf_release(req); | 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 | rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { | 3845 | rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { |
| 3832 | srch_inf->endOfSearch = true; | 3846 | srch_inf->endOfSearch = true; |
| 3833 | rc = 0; | 3847 | rc = 0; |
| 3834 | } | 3848 | } else |
| 3835 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); | 3849 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); |
| 3836 | goto qdir_exit; | 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 | rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); | 4441 | rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov); |
| 4428 | cifs_small_buf_release(req); | 4442 | cifs_small_buf_release(req); |
| 4429 | 4443 | ||
| 4430 | please_key_low = (__u64 *)req->LeaseKey; | 4444 | please_key_low = (__u64 *)lease_key; |
| 4431 | please_key_high = (__u64 *)(req->LeaseKey+8); | 4445 | please_key_high = (__u64 *)(lease_key+8); |
| 4432 | if (rc) { | 4446 | if (rc) { |
| 4433 | cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE); | 4447 | cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE); |
| 4434 | trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid, | 4448 | trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid, |
| @@ -84,8 +84,9 @@ · 83 unmodified lines | |||
| 84 | 84 | ||
| 85 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 | 85 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 |
| 86 | 86 | ||
| 87 | /* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */ | 87 | /* 52 transform hdr + 64 hdr + 88 create rsp */ |
| 88 | #define MAX_SMB2_HDR_SIZE 0x00b0 | 88 | #define SMB2_TRANSFORM_HEADER_SIZE 52 |
| 89 | #define MAX_SMB2_HDR_SIZE 204 | ||
| 89 | 90 | ||
| 90 | #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) | 91 | #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) |
| 91 | #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) | 92 | #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) |
| @@ -648,6 +649,13 @@ struct smb2_create_req { · 556 unmodified lines | |||
| 648 | __u8 Buffer[0]; | 649 | __u8 Buffer[0]; |
| 649 | } __packed; | 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 | struct smb2_create_rsp { | 659 | struct smb2_create_rsp { |
| 652 | struct smb2_sync_hdr sync_hdr; | 660 | struct smb2_sync_hdr sync_hdr; |
| 653 | __le16 StructureSize; /* Must be 89 */ | 661 | __le16 StructureSize; /* Must be 89 */ |
| @@ -996,6 +1004,11 @@ struct smb2_close_req { · 342 unmodified lines | |||
| 996 | __u64 VolatileFileId; /* opaque endianness */ | 1004 | __u64 VolatileFileId; /* opaque endianness */ |
| 997 | } __packed; | 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 | struct smb2_close_rsp { | 1012 | struct smb2_close_rsp { |
| 1000 | struct smb2_sync_hdr sync_hdr; | 1013 | struct smb2_sync_hdr sync_hdr; |
| 1001 | __le16 StructureSize; /* 60 */ | 1014 | __le16 StructureSize; /* 60 */ |
| @@ -1398,8 +1411,6 @@ struct smb2_file_link_info { /* encoding of request for level 11 */ · 396 unmodified lines | |||
| 1398 | char FileName[0]; /* Name to be assigned to new link */ | 1411 | char FileName[0]; /* Name to be assigned to new link */ |
| 1399 | } __packed; /* level 11 Set */ | 1412 | } __packed; /* level 11 Set */ |
| 1400 | 1413 | ||
| 1401 | #define SMB2_MAX_EA_BUF 65536 | ||
| 1402 | |||
| 1403 | struct smb2_file_full_ea_info { /* encoding of response for level 15 */ | 1414 | struct smb2_file_full_ea_info { /* encoding of response for level 15 */ |
| 1404 | __le32 next_entry_offset; | 1415 | __le32 next_entry_offset; |
| 1405 | __u8 flags; | 1416 | __u8 flags; |