summaryrefslogtreecommitdiffstats
path: root/fs/cifs/transport.c
Commit message (Collapse)AuthorAgeFilesLines
* cifs: only wake the thread for the very last PDU in a compoundRonnie Sahlberg2018-10-021-1/+17
| | | | | | | | | | | | | | | | | | | | | For compounded PDUs we whould only wake the waiting thread for the very last PDU of the compound. We do this so that we are guaranteed that the demultiplex_thread will not process or access any of those MIDs any more once the send/recv thread starts processing. Else there is a race where at the end of the send/recv processing we will try to delete all the mids of the compound. If the multiplex thread still has other mids to process at this point for this compound this can lead to an oops. Needed to fix recent commit: commit 730928c8f4be88e9d6a027a16b1e8fa9c59fc077 ("cifs: update smb2_queryfs() to use compounding") Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: add a warning if we try to to dequeue a deleted midRonnie Sahlberg2018-10-021-1/+2
| | | | | | | | | | | | | | | | | | cifs_delete_mid() is called once we are finished handling a mid and we expect no more work done on this mid. Needed to fix recent commit: commit 730928c8f4be88e9d6a027a16b1e8fa9c59fc077 ("cifs: update smb2_queryfs() to use compounding") Add a warning if someone tries to dequeue a mid that has already been flagged to be deleted. Also change list_del() to list_del_init() so that if we have similar bugs resurface in the future we will not oops. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: update receive_encrypted_standard to handle compounded responsesRonnie Sahlberg2018-08-091-2/+0
| | | | | | | Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Paulo Alcantara <palcantara@suse.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* smb3: display stats counters for number of slow commandsSteve French2018-08-071-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When CONFIG_CIFS_STATS2 is enabled keep counters for slow commands (ie server took longer than 1 second to respond) by SMB2/SMB3 command code. This can help in diagnosing whether performance problems are on server (instead of client) and which commands are causing the problem. Sample output (the new lines contain words "slow responses ...") $ cat /proc/fs/cifs/Stats Resources in use CIFS Session: 1 Share (unique mount targets): 2 SMB Request/Response Buffer: 1 Pool size: 5 SMB Small Req/Resp Buffer: 1 Pool size: 30 Total Large 10 Small 490 Allocations Operations (MIDs): 0 0 session 0 share reconnects Total vfs operations: 67 maximum at one time: 2 4 slow responses from localhost for command 5 1 slow responses from localhost for command 6 1 slow responses from localhost for command 14 1 slow responses from localhost for command 16 1) \\localhost\test SMBs: 243 Bytes read: 1024000 Bytes written: 104857600 TreeConnects: 1 total 0 failed TreeDisconnects: 0 total 0 failed Creates: 40 total 0 failed Closes: 39 total 0 failed ... Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com>
* smb3: add tracepoint for slow responsesSteve French2018-08-071-2/+6
| | | | | | | | | | | | | If responses take longer than one second from the server, we can optionally log them to dmesg in current cifs.ko code (CONFIG_CIFS_STATS2 must be configured and a /proc/fs/cifs/cifsFYI flag must be set), but can be more useful to log these via ftrace (tracepoint is smb3_slow_rsp) which is easier and more granular (still requires CONFIG_CIFS_STATS2 to be configured in the build though). Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: add compound_send_recv()Ronnie Sahlberg2018-08-071-66/+90
| | | | | | Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: make smb_send_rqst take an array of requestsRonnie Sahlberg2018-08-071-8/+13
| | | | | | Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: update init_sg, crypt_message to take an array of rqstRonnie Sahlberg2018-08-071-7/+20
| | | | | | | | | | These are used for SMB3 encryption and compounded requests. Update these functions and the other functions related to SMB3 encryption to take an array of requests. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* smb3: add reconnect tracepointsSteve French2018-08-071-0/+2
| | | | | | | | | | | | | | | | | | | | | Add tracepoints for reconnecting an smb3 session Example output (from trace-cmd) with the patch (showing the session marked for reconnect, the stat failing, and then the subsequent SMB3 commands after the server comes back up). The "smb3_reconnect" event is the new one. cifsd-25993 [000] .... 29635.368265: smb3_reconnect: server=localhost current_mid=0x1e stat-26200 [001] .... 29638.516403: smb3_enter: cifs_revalidate_dentry_attr: xid=22 stat-26200 [001] .... 29648.723296: smb3_exit_err: cifs_revalidate_dentry_attr: xid=22 rc=-112 kworker/0:1-22830 [000] .... 29653.850947: smb3_cmd_done: sid=0x0 tid=0x0 cmd=0 mid=0 kworker/0:1-22830 [000] .... 29653.851191: smb3_cmd_err: sid=0x8ae4683c tid=0x0 cmd=1 mid=1 status=0xc0000016 rc=-5 kworker/0:1-22830 [000] .... 29653.855254: smb3_cmd_done: sid=0x8ae4683c tid=0x0 cmd=1 mid=2 kworker/0:1-22830 [000] .... 29653.855482: smb3_cmd_done: sid=0x8ae4683c tid=0x8084f30d cmd=3 mid=3 Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com>
* smb3: simplify code by removing CONFIG_CIFS_SMB311Steve French2018-08-071-4/+0
| | | | | | | | | | | | | | | | | We really, really want to be encouraging use of secure dialects, and SMB3.1.1 offers useful security features, and will soon be the recommended dialect for many use cases. Simplify the code by removing the CONFIG_CIFS_SMB311 ifdef so users don't disable it in the build, and create compatibility and/or security issues with modern servers - many of which have been supporting this dialect for multiple years. Also clarify some of the Kconfig text for cifs.ko about SMB3.1.1 and current supported features in the module. Signed-off-by: Steve French <stfrench@microsoft.com> Acked-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
* cifs: fix SMB1 breakageRonnie Sahlberg2018-07-051-4/+5
| | | | | | | | | | | | | | SMB1 mounting broke in commit 35e2cc1ba755 ("cifs: Use correct packet length in SMB2_TRANSFORM header") Fix it and also rename smb2_rqst_len to smb_rqst_len to make it less unobvious that the function is also called from CIFS/SMB1 Good job by Paulo reviewing and cleaning up Ronnie's original patch. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Reviewed-by: Paulo Alcantara <palcantara@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
* cifs: Fix use after free of a mid_q_entryLars Persson2018-07-051-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With protocol version 2.0 mounts we have seen crashes with corrupt mid entries. Either the server->pending_mid_q list becomes corrupt with a cyclic reference in one element or a mid object fetched by the demultiplexer thread becomes overwritten during use. Code review identified a race between the demultiplexer thread and the request issuing thread. The demultiplexer thread seems to be written with the assumption that it is the sole user of the mid object until it calls the mid callback which either wakes the issuer task or deletes the mid. This assumption is not true because the issuer task can be woken up earlier by a signal. If the demultiplexer thread has proceeded as far as setting the mid_state to MID_RESPONSE_RECEIVED then the issuer thread will happily end up calling cifs_delete_mid while the demultiplexer thread still is using the mid object. Inserting a delay in the cifs demultiplexer thread widens the race window and makes reproduction of the race very easy: if (server->large_buf) buf = server->bigbuf; + usleep_range(500, 4000); server->lstrp = jiffies; To resolve this I think the proper solution involves putting a reference count on the mid object. This patch makes sure that the demultiplexer thread holds a reference until it has finished processing the transaction. Cc: stable@vger.kernel.org Signed-off-by: Lars Persson <larper@axis.com> Acked-by: Paulo Alcantara <palcantara@suse.de> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
* cifs: Use correct packet length in SMB2_TRANSFORM headerPaulo Alcantara2018-06-151-5/+14
| | | | | | | | | | | | | | | | | | | In smb3_init_transform_rq(), 'orig_len' was only counting the request length, but forgot to count any data pages in the request. Writing or creating files with the 'seal' mount option was broken. In addition, do some code refactoring by exporting smb2_rqst_len() to calculate the appropriate packet size and avoid duplicating the same calculation all over the code. The start of the io vector is either the rfc1002 length (4 bytes) or a SMB2 header which is always > 4. Use this fact to check and skip the rfc1002 length if requested. Signed-off-by: Paulo Alcantara <palcantara@suse.de> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
* cifs: Fix kernel oops when traceSMB is enabledPaulo Alcantara2018-06-151-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When traceSMB is enabled through 'echo 1 > /proc/fs/cifs/traceSMB', after a mount, the following oops is triggered: [ 27.137943] BUG: unable to handle kernel paging request at ffff8800f80c268b [ 27.143396] PGD 2c6b067 P4D 2c6b067 PUD 0 [ 27.145386] Oops: 0000 [#1] SMP PTI [ 27.146186] CPU: 2 PID: 2655 Comm: mount.cifs Not tainted 4.17.0+ #39 [ 27.147174] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 [ 27.148969] RIP: 0010:hex_dump_to_buffer+0x413/0x4b0 [ 27.149738] Code: 48 8b 44 24 08 31 db 45 31 d2 48 89 6c 24 18 44 89 6c 24 24 48 c7 c1 78 b5 23 82 4c 89 64 24 10 44 89 d5 41 89 dc 4c 8d 58 02 <44> 0f b7 00 4d 89 dd eb 1f 83 c5 01 41 01 c4 41 39 ef 0f 84 48 fe [ 27.152396] RSP: 0018:ffffc9000058f8c0 EFLAGS: 00010246 [ 27.153129] RAX: ffff8800f80c268b RBX: 0000000000000000 RCX: ffffffff8223b578 [ 27.153867] RDX: 0000000000000000 RSI: ffffffff81a55496 RDI: 0000000000000008 [ 27.154612] RBP: 0000000000000000 R08: 0000000000000020 R09: 0000000000000083 [ 27.155355] R10: 0000000000000000 R11: ffff8800f80c268d R12: 0000000000000000 [ 27.156101] R13: 0000000000000002 R14: ffffc9000058f94d R15: 0000000000000008 [ 27.156838] FS: 00007f1693a6b740(0000) GS:ffff88007fd00000(0000) knlGS:0000000000000000 [ 27.158354] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 27.159093] CR2: ffff8800f80c268b CR3: 00000000798fa001 CR4: 0000000000360ee0 [ 27.159892] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 27.160661] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 27.161464] Call Trace: [ 27.162123] print_hex_dump+0xd3/0x160 [ 27.162814] journal-offline (2658) used greatest stack depth: 13144 bytes left [ 27.162824] ? __release_sock+0x60/0xd0 [ 27.165344] ? tcp_sendmsg+0x31/0x40 [ 27.166177] dump_smb+0x39/0x40 [ 27.166972] ? vsnprintf+0x236/0x490 [ 27.167807] __smb_send_rqst.constprop.12+0x103/0x430 [ 27.168554] ? apic_timer_interrupt+0xa/0x20 [ 27.169306] smb_send_rqst+0x48/0xc0 [ 27.169984] cifs_send_recv+0xda/0x420 [ 27.170639] SMB2_negotiate+0x23d/0xfa0 [ 27.171301] ? vsnprintf+0x236/0x490 [ 27.171961] ? smb2_negotiate+0x19/0x30 [ 27.172586] smb2_negotiate+0x19/0x30 [ 27.173257] cifs_negotiate_protocol+0x70/0xd0 [ 27.173935] ? kstrdup+0x43/0x60 [ 27.174551] cifs_get_smb_ses+0x295/0xbe0 [ 27.175260] ? lock_timer_base+0x67/0x80 [ 27.175936] ? __internal_add_timer+0x1a/0x50 [ 27.176575] ? add_timer+0x10f/0x230 [ 27.177267] cifs_mount+0x101/0x1190 [ 27.177940] ? cifs_smb3_do_mount+0x144/0x5c0 [ 27.178575] cifs_smb3_do_mount+0x144/0x5c0 [ 27.179270] mount_fs+0x35/0x150 [ 27.179930] vfs_kern_mount.part.28+0x54/0xf0 [ 27.180567] do_mount+0x5ad/0xc40 [ 27.181234] ? kmem_cache_alloc_trace+0xed/0x1a0 [ 27.181916] ksys_mount+0x80/0xd0 [ 27.182535] __x64_sys_mount+0x21/0x30 [ 27.183220] do_syscall_64+0x4e/0x100 [ 27.183882] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 27.184535] RIP: 0033:0x7f169339055a [ 27.185192] Code: 48 8b 0d 41 d9 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 0e d9 2b 00 f7 d8 64 89 01 48 [ 27.187268] RSP: 002b:00007fff7b44eb58 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5 [ 27.188515] RAX: ffffffffffffffda RBX: 00007f1693a7e70e RCX: 00007f169339055a [ 27.189244] RDX: 000055b9f97f64e5 RSI: 000055b9f97f652c RDI: 00007fff7b45074f [ 27.189974] RBP: 000055b9fb8c9260 R08: 000055b9fb8ca8f0 R09: 0000000000000000 [ 27.190721] R10: 0000000000000000 R11: 0000000000000202 R12: 000055b9fb8ca8f0 [ 27.191429] R13: 0000000000000000 R14: 00007f1693a7c000 R15: 00007f1693a7e91d [ 27.192167] Modules linked in: [ 27.192797] CR2: ffff8800f80c268b [ 27.193435] ---[ end trace 67404c618badf323 ]--- The problem was that dump_smb() had been called with an invalid pointer, that is, in __smb_send_rqst(), iov[1] doesn't exist (n_vec == 1). This patch fixes it by relying on the n_vec value to dump out the smb packets. Signed-off-by: Paulo Alcantara <palcantara@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
* cifs: update __smb_send_rqst() to take an array of requestsRonnie Sahlberg2018-06-151-35/+44
| | | | | Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: remove smb2_send_recv()Ronnie Sahlberg2018-06-151-17/+0
| | | | | | | | | Now that we have the plumbing to pass request without an rfc1002 header all the way down to the point we write to the socket we no longer need the smb2_send_recv() function. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: push rfc1002 generation down the stackRonnie Sahlberg2018-06-151-50/+32
| | | | | | | | | Move the generation of the 4 byte length field down the stack and generate it immediately before we start writing the data to the socket. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <smfrench@gmail.com>
* treewide: kmalloc() -> kmalloc_array()Kees Cook2018-06-121-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The kmalloc() function has a 2-factor argument form, kmalloc_array(). This patch replaces cases of: kmalloc(a * b, gfp) with: kmalloc_array(a * b, gfp) as well as handling cases of: kmalloc(a * b * c, gfp) with: kmalloc(array3_size(a, b, c), gfp) as it's slightly less ugly than: kmalloc_array(array_size(a, b), c, gfp) This does, however, attempt to ignore constant size factors like: kmalloc(4 * 1024, gfp) though any constants defined via macros get caught up in the conversion. Any factors with a sizeof() of "unsigned char", "char", and "u8" were dropped, since they're redundant. The tools/ directory was manually excluded, since it has its own implementation of kmalloc(). The Coccinelle script used for this was: // Fix redundant parens around sizeof(). @@ type TYPE; expression THING, E; @@ ( kmalloc( - (sizeof(TYPE)) * E + sizeof(TYPE) * E , ...) | kmalloc( - (sizeof(THING)) * E + sizeof(THING) * E , ...) ) // Drop single-byte sizes and redundant parens. @@ expression COUNT; typedef u8; typedef __u8; @@ ( kmalloc( - sizeof(u8) * (COUNT) + COUNT , ...) | kmalloc( - sizeof(__u8) * (COUNT) + COUNT , ...) | kmalloc( - sizeof(char) * (COUNT) + COUNT , ...) | kmalloc( - sizeof(unsigned char) * (COUNT) + COUNT , ...) | kmalloc( - sizeof(u8) * COUNT + COUNT , ...) | kmalloc( - sizeof(__u8) * COUNT + COUNT , ...) | kmalloc( - sizeof(char) * COUNT + COUNT , ...) | kmalloc( - sizeof(unsigned char) * COUNT + COUNT , ...) ) // 2-factor product with sizeof(type/expression) and identifier or constant. @@ type TYPE; expression THING; identifier COUNT_ID; constant COUNT_CONST; @@ ( - kmalloc + kmalloc_array ( - sizeof(TYPE) * (COUNT_ID) + COUNT_ID, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(TYPE) * COUNT_ID + COUNT_ID, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(TYPE) * (COUNT_CONST) + COUNT_CONST, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(TYPE) * COUNT_CONST + COUNT_CONST, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * (COUNT_ID) + COUNT_ID, sizeof(THING) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * COUNT_ID + COUNT_ID, sizeof(THING) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * (COUNT_CONST) + COUNT_CONST, sizeof(THING) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * COUNT_CONST + COUNT_CONST, sizeof(THING) , ...) ) // 2-factor product, only identifiers. @@ identifier SIZE, COUNT; @@ - kmalloc + kmalloc_array ( - SIZE * COUNT + COUNT, SIZE , ...) // 3-factor product with 1 sizeof(type) or sizeof(expression), with // redundant parens removed. @@ expression THING; identifier STRIDE, COUNT; type TYPE; @@ ( kmalloc( - sizeof(TYPE) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kmalloc( - sizeof(TYPE) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kmalloc( - sizeof(TYPE) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kmalloc( - sizeof(TYPE) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | kmalloc( - sizeof(THING) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kmalloc( - sizeof(THING) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kmalloc( - sizeof(THING) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | kmalloc( - sizeof(THING) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) ) // 3-factor product with 2 sizeof(variable), with redundant parens removed. @@ expression THING1, THING2; identifier COUNT; type TYPE1, TYPE2; @@ ( kmalloc( - sizeof(TYPE1) * sizeof(TYPE2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | kmalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | kmalloc( - sizeof(THING1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | kmalloc( - sizeof(THING1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | kmalloc( - sizeof(TYPE1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) | kmalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) ) // 3-factor product, only identifiers, with redundant parens removed. @@ identifier STRIDE, SIZE, COUNT; @@ ( kmalloc( - (COUNT) * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - COUNT * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - COUNT * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - (COUNT) * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - COUNT * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - (COUNT) * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - (COUNT) * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | kmalloc( - COUNT * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) ) // Any remaining multi-factor products, first at least 3-factor products, // when they're not all constants... @@ expression E1, E2, E3; constant C1, C2, C3; @@ ( kmalloc(C1 * C2 * C3, ...) | kmalloc( - (E1) * E2 * E3 + array3_size(E1, E2, E3) , ...) | kmalloc( - (E1) * (E2) * E3 + array3_size(E1, E2, E3) , ...) | kmalloc( - (E1) * (E2) * (E3) + array3_size(E1, E2, E3) , ...) | kmalloc( - E1 * E2 * E3 + array3_size(E1, E2, E3) , ...) ) // And then all remaining 2 factors products when they're not all constants, // keeping sizeof() as the second factor argument. @@ expression THING, E1, E2; type TYPE; constant C1, C2, C3; @@ ( kmalloc(sizeof(THING) * C2, ...) | kmalloc(sizeof(TYPE) * C2, ...) | kmalloc(C1 * C2 * C3, ...) | kmalloc(C1 * C2, ...) | - kmalloc + kmalloc_array ( - sizeof(TYPE) * (E2) + E2, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(TYPE) * E2 + E2, sizeof(TYPE) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * (E2) + E2, sizeof(THING) , ...) | - kmalloc + kmalloc_array ( - sizeof(THING) * E2 + E2, sizeof(THING) , ...) | - kmalloc + kmalloc_array ( - (E1) * E2 + E1, E2 , ...) | - kmalloc + kmalloc_array ( - (E1) * (E2) + E1, E2 , ...) | - kmalloc + kmalloc_array ( - E1 * E2 + E1, E2 , ...) ) Signed-off-by: Kees Cook <keescook@chromium.org>
* CIFS: When sending data on socket, pass the correct page offsetLong Li2018-06-051-8/+6
| | | | | | | | It's possible that the offset is non-zero in the page to send, change the function to pass this offset to socket. Signed-off-by: Long Li <longli@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
* CIFS: Calculate the correct request length based on page offset and tail sizeLong Li2018-06-051-3/+17
| | | | | | | | It's possible that the page offset is non-zero in the pages in a request, change the function to calculate the correct data buffer length. Signed-off-by: Long Li <longli@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
* cifs: remove rfc1002 header from all SMB2 response structuresRonnie Sahlberg2018-05-311-2/+2
| | | | | | | | | | | | | | | Separate out all the 4 byte rfc1002 headers so that they are no longer part of the SMB2 header structures to prepare for future work to add compounding support. Update the smb3 transform header processing that we no longer have a rfc1002 header at the start of this structure. Update smb2_readv_callback to accommodate that the first iovector in the response is no the smb2 header and no longer a rfc1002 header. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
* SMB311: Fix reconnectSteve French2018-04-251-2/+2
| | | | | | | | | | | | The preauth hash was not being recalculated properly on reconnect of SMB3.11 dialect mounts (which caused access denied repeatedly on auto-reconnect). Fixes: 8bd68c6e47ab ("CIFS: implement v3.11 preauth integrity") Signed-off-by: Steve French <smfrench@gmail.com> CC: Stable <stable@vger.kernel.org> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
* CIFS: set *resp_buf_type to NO_BUFFER on errorSteve French2018-04-241-1/+4
| | | | | | | | | | | | | Dan Carpenter had pointed this out a while ago, but the code around this had changed so wasn't causing any problems since that field was not used in this error path. Still, it is cleaner to always initialize this field, so changing the error path to set it. Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> CC: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: add resp_buf_size to the mid_q_entry structureRonnie Sahlberg2018-04-121-1/+1
| | | | | | | | and get rid of some more calls to get_rfc1002_length() Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: add server->vals->header_preamble_sizeRonnie Sahlberg2018-04-021-1/+2
| | | | | | | | | | | | This variable is set to 4 for all protocol versions and replaces the hardcoded constant 4 throughought the code. This will later be updated to reflect whether a response packet has a 4 byte length preamble or not once we start removing this field from the SMB2+ dialects. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: implement v3.11 preauth integrityAurelien Aptel2018-04-011-0/+17
| | | | | | | | | | | | | | SMB3.11 clients must implement pre-authentification integrity. * new mechanism to certify requests/responses happening before Tree Connect. * supersedes VALIDATE_NEGOTIATE * fixes signing for SMB3.11 Signed-off-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <smfrench@gmail.com> CC: Stable <stable@vger.kernel.org> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
* CIFS: SMBD: Upper layer sends data via RDMA sendLong Li2018-01-241-2/+6
| | | | | | | | | With SMB Direct connected, use it for sending data via RDMA send. Signed-off-by: Long Li <longli@microsoft.com> Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
* cifs: avoid a kmalloc in smb2_send_recv/SendReceive2 for the common caseRonnie Sahlberg2018-01-241-10/+23
| | | | | | | | | | | | | | | | In both functions, use an array of 8 (arbitrary but should be big enough for all current uses) iov and avoid having to kmalloc the array for the common case. If 8 is too small, then fall back to the original behaviour and use kmalloc/kfree. This should not change any behaviour but should save us a tiny amount of cpu cycles. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: Add smb2_send_recvRonnie Sahlberg2018-01-241-0/+38
| | | | | | | | | This function is similar to SendReceive2 except it does not expect a 4 byte rfc1002 length header in the first io vector. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: Do not modify mid entry after submitting I/O in cifs_call_asyncLong Li2017-07-051-2/+5
| | | | | | | | | | | | | In cifs_call_async, server may respond as soon as I/O is submitted. Because mid entry is freed on the return path, it should not be modified after I/O is submitted. cifs_save_when_sent modifies the sent timestamp in mid entry, and should not be called after I/O. Call it before I/O. Signed-off-by: Long Li <longli@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <smfrench@gmail.com>
* fs: cifs: transport: Use time_after for time comparisonKarim Eshapa2017-05-121-1/+1
| | | | | | | | Use time_after kernel macro for time comparison that has safety check. Signed-off-by: Karim Eshapa <karim.eshapa@gmail.com> Signed-off-by: Steve French <smfrench@gmail.com>
* Don't delay freeing mids when blocked on slow socket write of requestSteve French2017-05-091-2/+0
| | | | | | | | | | | | | | | | | | When processing responses, and in particular freeing mids (DeleteMidQEntry), which is very important since it also frees the associated buffers (cifs_buf_release), we can block a long time if (writes to) socket is slow due to low memory or networking issues. We can block in send (smb request) waiting for memory, and be blocked in processing responess (which could free memory if we let it) - since they both grab the server->srv_mutex. In practice, in the DeleteMidQEntry case - there is no reason we need to grab the srv_mutex so remove these around DeleteMidQEntry, and it allows us to free memory faster. Signed-off-by: Steve French <steve.french@primarydata.com> Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
* cifs: don't check for failure from mempool_alloc()NeilBrown2017-04-281-18/+14
| | | | | | | | | | | mempool_alloc() cannot fail if the gfp flags allow it to sleep, and both GFP_FS allows for sleeping. So these tests of the return value from mempool_alloc() cannot be needed. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Steve French <smfrench@gmail.com>
* Handle mismatched open callsSachin Prabhu2017-04-071-0/+2
| | | | | | | | | | | | | | | | | | A signal can interrupt a SendReceive call which result in incoming responses to the call being ignored. This is a problem for calls such as open which results in the successful response being ignored. This results in an open file resource on the server. The patch looks into responses which were cancelled after being sent and in case of successful open closes the open fids. For this patch, the check is only done in SendReceive2() RH-bz: 1403319 Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Cc: Stable <stable@vger.kernel.org>
* CIFS: Add mid handle callbackPavel Shilovsky2017-02-011-2/+3
| | | | | | | | We need to process read responses differently because the data should go directly into preallocated pages. This can be done by specifying a mid handle callback. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: Add capability to transform requests before sendingPavel Shilovsky2017-02-011-8/+25
| | | | | | | | This will allow us to do protocol specific tranformations of packets before sending to the server. For SMB3 it can be used to support encryption. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: Separate RFC1001 length processing for SMB2 readPavel Shilovsky2017-02-011-1/+1
| | | | | | | | Allocate and initialize SMB2 read request without RFC1001 length field to directly call cifs_send_recv() rather than SendReceive2() in a read codepath. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: Send RFC1001 length in a separate iovPavel Shilovsky2017-02-011-21/+65
| | | | | | | | In order to simplify further encryption support we need to separate RFC1001 length and SMB2 header when sending a request. Put the length field in iov[0] and the rest of the packet into following iovs. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: Make send_cancel take rqst as argumentPavel Shilovsky2017-02-011-14/+19
| | | | Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* CIFS: Make SendReceive2() takes resp iovPavel Shilovsky2017-02-011-21/+9
| | | | | | | | | Now SendReceive2 frees the first iov and returns a response buffer in it that increases a code complexity. Simplify this by making a caller responsible for freeing request buffer itself and returning a response buffer in a separate iov. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
* Replace <asm/uaccess.h> with <linux/uaccess.h> globallyLinus Torvalds2016-12-241-1/+1
| | | | | | | | | | | | | This was entirely automated, using the script by Al: PATT='^[[:blank:]]*#[[:blank:]]*include[[:blank:]]*<asm/uaccess.h>' sed -i -e "s!$PATT!#include <linux/uaccess.h>!" \ $(git grep -l "$PATT"|grep -v ^include/linux/uaccess.h) to do the replacement at the end of the merge window. Requested-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* block,fs: untangle fs.h and blk_types.hChristoph Hellwig2016-11-011-0/+1
| | | | | | | Nothing in fs.h should require blk_types.h to be included. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
* cifs: quit playing games with draining iovecsAl Viro2016-03-281-100/+41
| | | | | | ... and use ITER_BVEC for the page part of request to send Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: fix race between call_async() and reconnect()Rabin Vincent2016-01-141-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | cifs_call_async() queues the MID to the pending list and calls smb_send_rqst(). If smb_send_rqst() performs a partial send, it sets the tcpStatus to CifsNeedReconnect and returns an error code to cifs_call_async(). In this case, cifs_call_async() removes the MID from the list and returns to the caller. However, cifs_call_async() releases the server mutex _before_ removing the MID. This means that a cifs_reconnect() can race with this function and manage to remove the MID from the list and delete the entry before cifs_call_async() calls cifs_delete_mid(). This leads to various crashes due to the use after free in cifs_delete_mid(). Task1 Task2 cifs_call_async(): - rc = -EAGAIN - mutex_unlock(srv_mutex) cifs_reconnect(): - mutex_lock(srv_mutex) - mutex_unlock(srv_mutex) - list_delete(mid) - mid->callback() cifs_writev_callback(): - mutex_lock(srv_mutex) - delete(mid) - mutex_unlock(srv_mutex) - cifs_delete_mid(mid) <---- use after free Fix this by removing the MID in cifs_call_async() before releasing the srv_mutex. Also hold the srv_mutex in cifs_reconnect() until the MIDs are moved out of the pending list. Signed-off-by: Rabin Vincent <rabin.vincent@axis.com> Acked-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> CC: Stable <stable@vger.kernel.org> Signed-off-by: Steve French <sfrench@localhost.localdomain>
* cifs: Fix use-after-free on mid_q_entryChristopher Oo2015-08-201-0/+2
| | | | | | | | | | With CIFS_DEBUG_2 enabled, additional debug information is tracked inside each mid_q_entry struct, however cifs_save_when_sent may use the mid_q_entry after it has been freed from the appropriate callback if the transport layer has very low latency. Holding the srv_mutex fixes this use-after-free, as cifs_save_when_sent is called while the srv_mutex is held while the request is sent. Signed-off-by: Christopher Oo <t-chriso@microsoft.com>
* cifs: convert printk(LEVEL...) to pr_<level>Andy Shevchenko2014-12-071-2/+2
| | | | | | | | | The useful macros embed message level in the name. Thus, it cleans up the code a bit. In cases when it was plain printk() the conversion was done to info level. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Steve French <steve.french@primarydata.com>
* CIFS: Use multicredits for SMB 2.1/3 writesPavel Shilovsky2014-08-021-7/+18
| | | | | | | | | | | | If we negotiate SMB 2.1 and higher version of the protocol and a server supports large write buffer size, we need to consume 1 credit per 65536 bytes. So, we need to know how many credits we have and obtain the required number of them before constructing a writedata structure in writepages and iovec write. Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: sanity check length of data to send before sendingJeff Layton2014-02-231-0/+29
| | | | | | | | | | | | | | | | | We had a bug discovered recently where an upper layer function (cifs_iovec_write) could pass down a smb_rqst with an invalid amount of data in it. The length of the SMB frame would be correct, but the rqst struct would cause smb_send_rqst to send nearly 4GB of data. This should never be the case. Add some sanity checking to the beginning of smb_send_rqst that ensures that the amount of data we're going to send agrees with the length in the RFC1002 header. If it doesn't, WARN() and return -EIO to the upper layers. Signed-off-by: Jeff Layton <jlayton@redhat.com> Acked-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: Send a logoff request before removing a smb sessionShirish Pargaonkar2013-11-021-2/+9
| | | | | | | | | | | | | | | | Send a smb session logoff request before removing smb session off of the list. On a signed smb session, remvoing a session off of the list before sending a logoff request results in server returning an error for lack of smb signature. Never seen an error during smb logoff, so as per MS-SMB2 3.2.5.1, not sure how an error during logoff should be retried. So for now, if a server returns an error to a logoff request, log the error and remove the session off of the list. Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* cifs: Make big endian multiplex ID sequences monotonic on the wireTim Gardner2013-11-021-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The multiplex identifier (MID) in the SMB header is only ever used by the client, in conjunction with PID, to match responses from the server. As such, the endianess of the MID is not important. However, When tracing packet sequences on the wire, protocol analyzers such as wireshark display MID as little endian. It is much more informative for the on-the-wire MID sequences to match debug information emitted by the CIFS driver. Therefore, one should write and read MID in the SMB header assuming it is always little endian. Observed from wireshark during the protocol negotiation and session setup: Multiplex ID: 256 Multiplex ID: 256 Multiplex ID: 512 Multiplex ID: 512 Multiplex ID: 768 Multiplex ID: 768 After this patch on-the-wire MID values begin at 1 and increase monotonically. Introduce get_next_mid64() for the internal consumers that use the full 64 bit multiplex identifier. Introduce the helpers get_mid() and compare_mid() to make the endian translation clear. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Tim Gardner <timg@tpi.com> Signed-off-by: Steve French <smfrench@gmail.com>