1. 23 1月, 2021 1 次提交
    • R
      cifs: do not fail __smb_send_rqst if non-fatal signals are pending · 214a5ea0
      Ronnie Sahlberg 提交于
      RHBZ 1848178
      
      The original intent of returning an error in this function
      in the patch:
        "CIFS: Mask off signals when sending SMB packets"
      was to avoid interrupting packet send in the middle of
      sending the data (and thus breaking an SMB connection),
      but we also don't want to fail the request for non-fatal
      signals even before we have had a chance to try to
      send it (the reported problem could be reproduced e.g.
      by exiting a child process when the parent process was in
      the midst of calling futimens to update a file's timestamps).
      
      In addition, since the signal may remain pending when we enter the
      sending loop, we may end up not sending the whole packet before
      TCP buffers become full. In this case the code returns -EINTR
      but what we need here is to return -ERESTARTSYS instead to
      allow system calls to be restarted.
      
      Fixes: b30c74c7 ("CIFS: Mask off signals when sending SMB packets")
      Cc: stable@vger.kernel.org # v5.1+
      Signed-off-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      214a5ea0
  2. 16 12月, 2020 1 次提交
  3. 01 12月, 2020 1 次提交
    • P
      cifs: allow syscalls to be restarted in __smb_send_rqst() · 6988a619
      Paulo Alcantara 提交于
      A customer has reported that several files in their multi-threaded app
      were left with size of 0 because most of the read(2) calls returned
      -EINTR and they assumed no bytes were read.  Obviously, they could
      have fixed it by simply retrying on -EINTR.
      
      We noticed that most of the -EINTR on read(2) were due to real-time
      signals sent by glibc to process wide credential changes (SIGRT_1),
      and its signal handler had been established with SA_RESTART, in which
      case those calls could have been automatically restarted by the
      kernel.
      
      Let the kernel decide to whether or not restart the syscalls when
      there is a signal pending in __smb_send_rqst() by returning
      -ERESTARTSYS.  If it can't, it will return -EINTR anyway.
      Signed-off-by: NPaulo Alcantara (SUSE) <pc@cjr.nz>
      CC: Stable <stable@vger.kernel.org>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      6988a619
  4. 21 10月, 2020 1 次提交
  5. 03 8月, 2020 1 次提交
  6. 02 7月, 2020 1 次提交
  7. 05 6月, 2020 1 次提交
    • A
      cifs: multichannel: move channel selection above transport layer · 352d96f3
      Aurelien Aptel 提交于
      Move the channel (TCP_Server_Info*) selection from the tranport
      layer to higher in the call stack so that:
      
      - credit handling is done with the server that will actually be used
        to send.
        * ->wait_mtu_credit
        * ->set_credits / set_credits
        * ->add_credits / add_credits
        * add_credits_and_wake_if
      
      - potential reconnection (smb2_reconnect) done when initializing a
        request is checked and done with the server that will actually be
        used to send.
      
      To do this:
      
      - remove the cifs_pick_channel() call out of compound_send_recv()
      
      - select channel and pass it down by adding a cifs_pick_channel(ses)
        call in:
        - smb311_posix_mkdir
        - SMB2_open
        - SMB2_ioctl
        - __SMB2_close
        - query_info
        - SMB2_change_notify
        - SMB2_flush
        - smb2_async_readv  (if none provided in context param)
        - SMB2_read         (if none provided in context param)
        - smb2_async_writev (if none provided in context param)
        - SMB2_write        (if none provided in context param)
        - SMB2_query_directory
        - send_set_info
        - SMB2_oplock_break
        - SMB311_posix_qfs_info
        - SMB2_QFS_info
        - SMB2_QFS_attr
        - smb2_lockv
        - SMB2_lease_break
          - smb2_compound_op
        - smb2_set_ea
        - smb2_ioctl_query_info
        - smb2_query_dir_first
        - smb2_query_info_comound
        - smb2_query_symlink
        - cifs_writepages
        - cifs_write_from_iter
        - cifs_send_async_read
        - cifs_read
        - cifs_readpages
      
      - add TCP_Server_Info *server param argument to:
        - cifs_send_recv
        - compound_send_recv
        - SMB2_open_init
        - SMB2_query_info_init
        - SMB2_set_info_init
        - SMB2_close_init
        - SMB2_ioctl_init
        - smb2_iotcl_req_init
        - SMB2_query_directory_init
        - SMB2_notify_init
        - SMB2_flush_init
        - build_qfs_info_req
        - smb2_hdr_assemble
        - smb2_reconnect
        - fill_small_buf
        - smb2_plain_req_init
        - __smb2_plain_req_init
      
      The read/write codepath is different than the rest as it is using
      pages, io iterators and async calls. To deal with those we add a
      server pointer in the cifs_writedata/cifs_readdata/cifs_io_parms
      context struct and set it in:
      
      - cifs_writepages      (wdata)
      - cifs_write_from_iter (wdata)
      - cifs_readpages       (rdata)
      - cifs_send_async_read (rdata)
      
      The [rw]data->server pointer is eventually copied to
      cifs_io_parms->server to pass it down to SMB2_read/SMB2_write.
      If SMB2_read/SMB2_write is called from a different place that doesn't
      set the server field it will pick a channel.
      
      Some places do not pick a channel and just use ses->server or
      cifs_ses_server(ses). All cifs_ses_server(ses) calls are in codepaths
      involving negprot/sess.setup.
      
      - SMB2_negotiate         (binding channel)
      - SMB2_sess_alloc_buffer (binding channel)
      - SMB2_echo              (uses provided one)
      - SMB2_logoff            (uses master)
      - SMB2_tdis              (uses master)
      
      (list not exhaustive)
      Signed-off-by: NAurelien Aptel <aaptel@suse.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      352d96f3
  8. 02 6月, 2020 1 次提交
  9. 01 6月, 2020 1 次提交
    • J
      cifs: Standardize logging output · a0a3036b
      Joe Perches 提交于
      Use pr_fmt to standardize all logging for fs/cifs.
      
      Some logging output had no CIFS: specific prefix.
      
      Now all output has one of three prefixes:
      
      o CIFS:
      o CIFS: VFS:
      o Root-CIFS:
      
      Miscellanea:
      
      o Convert printks to pr_<level>
      o Neaten macro definitions
      o Remove embedded CIFS: prefixes from formats
      o Convert "illegal" to "invalid"
      o Coalesce formats
      o Add missing '\n' format terminations
      o Consolidate multiple cifs_dbg continuations into single calls
      o More consistent use of upper case first word output logging
      o Multiline statement argument alignment and wrapping
      Signed-off-by: NJoe Perches <joe@perches.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      a0a3036b
  10. 29 5月, 2020 1 次提交
  11. 30 3月, 2020 1 次提交
  12. 27 1月, 2020 1 次提交
    • V
      CIFS: Fix task struct use-after-free on reconnect · f1f27ad7
      Vincent Whitchurch 提交于
      The task which created the MID may be gone by the time cifsd attempts to
      call the callbacks on MIDs from cifs_reconnect().
      
      This leads to a use-after-free of the task struct in cifs_wake_up_task:
      
       ==================================================================
       BUG: KASAN: use-after-free in __lock_acquire+0x31a0/0x3270
       Read of size 8 at addr ffff8880103e3a68 by task cifsd/630
      
       CPU: 0 PID: 630 Comm: cifsd Not tainted 5.5.0-rc6+ #119
       Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
       Call Trace:
        dump_stack+0x8e/0xcb
        print_address_description.constprop.5+0x1d3/0x3c0
        ? __lock_acquire+0x31a0/0x3270
        __kasan_report+0x152/0x1aa
        ? __lock_acquire+0x31a0/0x3270
        ? __lock_acquire+0x31a0/0x3270
        kasan_report+0xe/0x20
        __lock_acquire+0x31a0/0x3270
        ? __wake_up_common+0x1dc/0x630
        ? _raw_spin_unlock_irqrestore+0x4c/0x60
        ? mark_held_locks+0xf0/0xf0
        ? _raw_spin_unlock_irqrestore+0x39/0x60
        ? __wake_up_common_lock+0xd5/0x130
        ? __wake_up_common+0x630/0x630
        lock_acquire+0x13f/0x330
        ? try_to_wake_up+0xa3/0x19e0
        _raw_spin_lock_irqsave+0x38/0x50
        ? try_to_wake_up+0xa3/0x19e0
        try_to_wake_up+0xa3/0x19e0
        ? cifs_compound_callback+0x178/0x210
        ? set_cpus_allowed_ptr+0x10/0x10
        cifs_reconnect+0xa1c/0x15d0
        ? generic_ip_connect+0x1860/0x1860
        ? rwlock_bug.part.0+0x90/0x90
        cifs_readv_from_socket+0x479/0x690
        cifs_read_from_socket+0x9d/0xe0
        ? cifs_readv_from_socket+0x690/0x690
        ? mempool_resize+0x690/0x690
        ? rwlock_bug.part.0+0x90/0x90
        ? memset+0x1f/0x40
        ? allocate_buffers+0xff/0x340
        cifs_demultiplex_thread+0x388/0x2a50
        ? cifs_handle_standard+0x610/0x610
        ? rcu_read_lock_held_common+0x120/0x120
        ? mark_lock+0x11b/0xc00
        ? __lock_acquire+0x14ed/0x3270
        ? __kthread_parkme+0x78/0x100
        ? lockdep_hardirqs_on+0x3e8/0x560
        ? lock_downgrade+0x6a0/0x6a0
        ? lockdep_hardirqs_on+0x3e8/0x560
        ? _raw_spin_unlock_irqrestore+0x39/0x60
        ? cifs_handle_standard+0x610/0x610
        kthread+0x2bb/0x3a0
        ? kthread_create_worker_on_cpu+0xc0/0xc0
        ret_from_fork+0x3a/0x50
      
       Allocated by task 649:
        save_stack+0x19/0x70
        __kasan_kmalloc.constprop.5+0xa6/0xf0
        kmem_cache_alloc+0x107/0x320
        copy_process+0x17bc/0x5370
        _do_fork+0x103/0xbf0
        __x64_sys_clone+0x168/0x1e0
        do_syscall_64+0x9b/0xec0
        entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
       Freed by task 0:
        save_stack+0x19/0x70
        __kasan_slab_free+0x11d/0x160
        kmem_cache_free+0xb5/0x3d0
        rcu_core+0x52f/0x1230
        __do_softirq+0x24d/0x962
      
       The buggy address belongs to the object at ffff8880103e32c0
        which belongs to the cache task_struct of size 6016
       The buggy address is located 1960 bytes inside of
        6016-byte region [ffff8880103e32c0, ffff8880103e4a40)
       The buggy address belongs to the page:
       page:ffffea000040f800 refcount:1 mapcount:0 mapping:ffff8880108da5c0
       index:0xffff8880103e4c00 compound_mapcount: 0
       raw: 4000000000010200 ffffea00001f2208 ffffea00001e3408 ffff8880108da5c0
       raw: ffff8880103e4c00 0000000000050003 00000001ffffffff 0000000000000000
       page dumped because: kasan: bad access detected
      
       Memory state around the buggy address:
        ffff8880103e3900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
        ffff8880103e3980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
       >ffff8880103e3a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                                                 ^
        ffff8880103e3a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
        ffff8880103e3b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
       ==================================================================
      
      This can be reliably reproduced by adding the below delay to
      cifs_reconnect(), running find(1) on the mount, restarting the samba
      server while find is running, and killing find during the delay:
      
        	spin_unlock(&GlobalMid_Lock);
        	mutex_unlock(&server->srv_mutex);
      
       +	msleep(10000);
       +
        	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
        	list_for_each_safe(tmp, tmp2, &retry_list) {
        		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
      
      Fix this by holding a reference to the task struct until the MID is
      freed.
      Signed-off-by: NVincent Whitchurch <vincent.whitchurch@axis.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      CC: Stable <stable@vger.kernel.org>
      Reviewed-by: NPaulo Alcantara (SUSE) <pc@cjr.nz>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      f1f27ad7
  13. 25 11月, 2019 5 次提交
    • A
      cifs: try opening channels after mounting · d70e9fa5
      Aurelien Aptel 提交于
      After doing mount() successfully we call cifs_try_adding_channels()
      which will open as many channels as it can.
      
      Channels are closed when the master session is closed.
      
      The master connection becomes the first channel.
      
      ,-------------> global cifs_tcp_ses_list <-------------------------.
      |                                                                  |
      '- TCP_Server_Info  <-->  TCP_Server_Info  <-->  TCP_Server_Info <-'
            (master con)           (chan#1 con)         (chan#2 con)
            |      ^                    ^                    ^
            v      '--------------------|--------------------'
         cifs_ses                       |
         - chan_count = 3               |
         - chans[] ---------------------'
         - smb3signingkey[]
            (master signing key)
      
      Note how channel connections don't have sessions. That's because
      cifs_ses can only be part of one linked list (list_head are internal
      to the elements).
      
      For signing keys, each channel has its own signing key which must be
      used only after the channel has been bound. While it's binding it must
      use the master session signing key.
      
      For encryption keys, since channel connections do not have sessions
      attached we must now find matching session by looping over all sessions
      in smb2_get_enc_key().
      
      Each channel is opened like a regular server connection but at the
      session setup request step it must set the
      SMB2_SESSION_REQ_FLAG_BINDING flag and use the session id to bind to.
      
      Finally, while sending in compound_send_recv() for requests that
      aren't negprot, ses-setup or binding related, use a channel by cycling
      through the available ones (round-robin).
      Signed-off-by: NAurelien Aptel <aaptel@suse.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      d70e9fa5
    • A
      cifs: add server param · f780bd3f
      Aurelien Aptel 提交于
      As we get down to the transport layer, plenty of functions are passed
      the session pointer and assume the transport to use is ses->server.
      
      Instead we modify those functions to pass (ses, server) so that we
      can decouple the session from the server.
      Signed-off-by: NAurelien Aptel <aaptel@suse.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      f780bd3f
    • L
      cifs: smbd: Return -EAGAIN when transport is reconnecting · 4357d45f
      Long Li 提交于
      During reconnecting, the transport may have already been destroyed and is in
      the process being reconnected. In this case, return -EAGAIN to not fail and
      to retry this I/O.
      Signed-off-by: NLong Li <longli@microsoft.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      4357d45f
    • P
      CIFS: Do not miss cancelled OPEN responses · 7b71843f
      Pavel Shilovsky 提交于
      When an OPEN command is cancelled we mark a mid as
      cancelled and let the demultiplex thread process it
      by closing an open handle. The problem is there is
      a race between a system call thread and the demultiplex
      thread and there may be a situation when the mid has
      been already processed before it is set as cancelled.
      
      Fix this by processing cancelled requests when mids
      are being destroyed which means that there is only
      one thread referencing a particular mid. Also set
      mids as cancelled unconditionally on their state.
      
      Cc: Stable <stable@vger.kernel.org>
      Tested-by: NFrank Sorenson <sorenson@redhat.com>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      7b71843f
    • D
      cifs: rename a variable in SendReceive() · 8bd3754c
      Dan Carpenter 提交于
      Smatch gets confused because we sometimes refer to "server->srv_mutex" and
      sometimes to "sess->server->srv_mutex".  They refer to the same lock so
      let's just make this consistent.
      Signed-off-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      8bd3754c
  14. 25 10月, 2019 1 次提交
    • P
      CIFS: Fix retry mid list corruption on reconnects · abe57073
      Pavel Shilovsky 提交于
      When the client hits reconnect it iterates over the mid
      pending queue marking entries for retry and moving them
      to a temporary list to issue callbacks later without holding
      GlobalMid_Lock. In the same time there is no guarantee that
      mids can't be removed from the temporary list or even
      freed completely by another thread. It may cause a temporary
      list corruption:
      
      [  430.454897] list_del corruption. prev->next should be ffff98d3a8f316c0, but was 2e885cb266355469
      [  430.464668] ------------[ cut here ]------------
      [  430.466569] kernel BUG at lib/list_debug.c:51!
      [  430.468476] invalid opcode: 0000 [#1] SMP PTI
      [  430.470286] CPU: 0 PID: 13267 Comm: cifsd Kdump: loaded Not tainted 5.4.0-rc3+ #19
      [  430.473472] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
      [  430.475872] RIP: 0010:__list_del_entry_valid.cold+0x31/0x55
      ...
      [  430.510426] Call Trace:
      [  430.511500]  cifs_reconnect+0x25e/0x610 [cifs]
      [  430.513350]  cifs_readv_from_socket+0x220/0x250 [cifs]
      [  430.515464]  cifs_read_from_socket+0x4a/0x70 [cifs]
      [  430.517452]  ? try_to_wake_up+0x212/0x650
      [  430.519122]  ? cifs_small_buf_get+0x16/0x30 [cifs]
      [  430.521086]  ? allocate_buffers+0x66/0x120 [cifs]
      [  430.523019]  cifs_demultiplex_thread+0xdc/0xc30 [cifs]
      [  430.525116]  kthread+0xfb/0x130
      [  430.526421]  ? cifs_handle_standard+0x190/0x190 [cifs]
      [  430.528514]  ? kthread_park+0x90/0x90
      [  430.530019]  ret_from_fork+0x35/0x40
      
      Fix this by obtaining extra references for mids being retried
      and marking them as MID_DELETED which indicates that such a mid
      has been dequeued from the pending list.
      
      Also move mid cleanup logic from DeleteMidQEntry to
      _cifs_mid_q_entry_release which is called when the last reference
      to a particular mid is put. This allows to avoid any use-after-free
      of response buffers.
      
      The patch needs to be backported to stable kernels. A stable tag
      is not mentioned below because the patch doesn't apply cleanly
      to any actively maintained stable kernel.
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed-and-tested-by: NDavid Wysochanski <dwysocha@redhat.com>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      abe57073
  15. 17 9月, 2019 4 次提交
  16. 08 7月, 2019 1 次提交
  17. 13 5月, 2019 1 次提交
  18. 08 5月, 2019 4 次提交
  19. 15 3月, 2019 7 次提交
  20. 06 3月, 2019 5 次提交