30 Dec, 2020

1 commit

  • commit bc7c4129d4cdc56d1b5477c1714246f27df914dd upstream.

    Azure does not send an SPNEGO blob in the negotiate protocol response,
    so we shouldn't assume that it is there when validating the location
    of the first negotiate context. This avoids the potential confusing
    mount warning:

    CIFS: Invalid negotiate context offset

    CC: Stable
    Reviewed-by: Pavel Shilovsky
    Signed-off-by: Steve French
    Signed-off-by: Greg Kroah-Hartman

    Steve French
     

03 Aug, 2020

1 commit

  • Handling a lease break for the cached root didn't free the
    smb2_lease_break_work allocation, resulting in a leak:

    unreferenced object 0xffff98383a5af480 (size 128):
    comm "cifsd", pid 684, jiffies 4294936606 (age 534.868s)
    hex dump (first 32 bytes):
    c0 ff ff ff 1f 00 00 00 88 f4 5a 3a 38 98 ff ff ..........Z:8...
    88 f4 5a 3a 38 98 ff ff 80 88 d6 8a ff ff ff ff ..Z:8...........
    backtrace:
    [] smb2_is_valid_oplock_break+0x1fa/0x8c0
    [] cifs_demultiplex_thread+0x73d/0xcc0
    [] kthread+0x11c/0x150
    [] ret_from_fork+0x22/0x30

    Avoid this leak by only allocating when necessary.

    Fixes: a93864d93977 ("cifs: add lease tracking to the cached root fid")
    Signed-off-by: Paul Aurich
    CC: Stable # v4.18+
    Reviewed-by: Aurelien Aptel
    Signed-off-by: Steve French

    Paul Aurich
     

08 Jul, 2020

1 commit


01 Jun, 2020

1 commit

  • 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_
    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: Joe Perches
    Signed-off-by: Steve French

    Joe Perches
     

08 Apr, 2020

1 commit

  • Fix tcon use-after-free and NULL ptr deref.

    Customer system crashes with the following kernel log:

    [462233.169868] CIFS VFS: Cancelling wait for mid 4894753 cmd: 14 => a QUERY DIR
    [462233.228045] CIFS VFS: cifs_put_smb_ses: Session Logoff failure rc=-4
    [462233.305922] CIFS VFS: cifs_put_smb_ses: Session Logoff failure rc=-4
    [462233.306205] CIFS VFS: cifs_put_smb_ses: Session Logoff failure rc=-4
    [462233.347060] CIFS VFS: cifs_put_smb_ses: Session Logoff failure rc=-4
    [462233.347107] CIFS VFS: Close unmatched open
    [462233.347113] BUG: unable to handle kernel NULL pointer dereference at 0000000000000038
    ...
    [exception RIP: cifs_put_tcon+0xa0] (this is doing tcon->ses->server)
    #6 [...] smb2_cancelled_close_fid at ... [cifs]
    #7 [...] process_one_work at ...
    #8 [...] worker_thread at ...
    #9 [...] kthread at ...

    The most likely explanation we have is:

    * When we put the last reference of a tcon (refcount=0), we close the
    cached share root handle.
    * If closing a handle is interrupted, SMB2_close() will
    queue a SMB2_close() in a work thread.
    * The queued object keeps a tcon ref so we bump the tcon
    refcount, jumping from 0 to 1.
    * We reach the end of cifs_put_tcon(), we free the tcon object despite
    it now having a refcount of 1.
    * The queued work now runs, but the tcon, ses & server was freed in
    the meantime resulting in a crash.

    THREAD 1
    ========
    cifs_put_tcon => tcon refcount reach 0
    SMB2_tdis
    close_shroot_lease
    close_shroot_lease_locked => if cached root has lease && refcount = 0
    smb2_close_cached_fid => if cached root valid
    SMB2_close => retry close in a thread if interrupted
    smb2_handle_cancelled_close
    __smb2_handle_cancelled_close => !! tcon refcount bump 0 => 1 !!
    INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
    queue_work(cifsiod_wq, &cancelled->work) => queue work
    tconInfoFree(tcon); ==> freed!
    cifs_put_smb_ses(ses); ==> freed!

    THREAD 2 (workqueue)
    ========
    smb2_cancelled_close_fid
    SMB2_close(0, cancelled->tcon, ...); => use-after-free of tcon
    cifs_put_tcon(cancelled->tcon); => tcon refcount reach 0 second time
    *CRASH*

    Fixes: d9191319358d ("CIFS: Close cached root handle only if it has a lease")
    Signed-off-by: Aurelien Aptel
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky

    Aurelien Aptel
     

27 Jan, 2020

1 commit

  • __smb2_handle_cancelled_cmd() is called under a spin lock held in
    cifs_mid_q_entry_release(), so make its memory allocation GFP_ATOMIC.

    This issue was observed when running xfstests generic/028:

    [ 1722.589204] CIFS VFS: \\192.168.30.26 Cancelling wait for mid 72064 cmd: 5
    [ 1722.590687] CIFS VFS: \\192.168.30.26 Cancelling wait for mid 72065 cmd: 17
    [ 1722.593529] CIFS VFS: \\192.168.30.26 Cancelling wait for mid 72066 cmd: 6
    [ 1723.039014] BUG: sleeping function called from invalid context at mm/slab.h:565
    [ 1723.040710] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 30877, name: cifsd
    [ 1723.045098] CPU: 3 PID: 30877 Comm: cifsd Not tainted 5.5.0-rc4+ #313
    [ 1723.046256] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014
    [ 1723.048221] Call Trace:
    [ 1723.048689] dump_stack+0x97/0xe0
    [ 1723.049268] ___might_sleep.cold+0xd1/0xe1
    [ 1723.050069] kmem_cache_alloc_trace+0x204/0x2b0
    [ 1723.051051] __smb2_handle_cancelled_cmd+0x40/0x140 [cifs]
    [ 1723.052137] smb2_handle_cancelled_mid+0xf6/0x120 [cifs]
    [ 1723.053247] cifs_mid_q_entry_release+0x44d/0x630 [cifs]
    [ 1723.054351] ? cifs_reconnect+0x26a/0x1620 [cifs]
    [ 1723.055325] cifs_demultiplex_thread+0xad4/0x14a0 [cifs]
    [ 1723.056458] ? cifs_handle_standard+0x2c0/0x2c0 [cifs]
    [ 1723.057365] ? kvm_sched_clock_read+0x14/0x30
    [ 1723.058197] ? sched_clock+0x5/0x10
    [ 1723.058838] ? sched_clock_cpu+0x18/0x110
    [ 1723.059629] ? lockdep_hardirqs_on+0x17d/0x250
    [ 1723.060456] kthread+0x1ab/0x200
    [ 1723.061149] ? cifs_handle_standard+0x2c0/0x2c0 [cifs]
    [ 1723.062078] ? kthread_create_on_node+0xd0/0xd0
    [ 1723.062897] ret_from_fork+0x3a/0x50

    Signed-off-by: Paulo Alcantara (SUSE)
    Fixes: 9150c3adbf24 ("CIFS: Close open handle after interrupted close")
    Cc: Stable
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky

    Paulo Alcantara (SUSE)
     

25 Nov, 2019

6 commits

  • Currenly we doesn't assume that a server may break a lease
    from RWH to RW which causes us setting a wrong lease state
    on a file and thus mistakenly flushing data and byte-range
    locks and purging cached data on the client. This leads to
    performance degradation because subsequent IOs go directly
    to the server.

    Fix this by propagating new lease state and epoch values
    to the oplock break handler through cifsFileInfo structure
    and removing the use of cifsInodeInfo flags for that. It
    allows to avoid some races of several lease/oplock breaks
    using those flags in parallel.

    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     
  • 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
    Signed-off-by: Steve French

    Aurelien Aptel
     
  • Even when mounting modern protocol version the server may be
    configured without supporting SMB2.1 leases and the client
    uses SMB2 oplock to optimize IO performance through local caching.

    However there is a problem in oplock break handling that leads
    to missing a break notification on the client who has a file
    opened. It latter causes big latencies to other clients that
    are trying to open the same file.

    The problem reproduces when there are multiple shares from the
    same server mounted on the client. The processing code tries to
    match persistent and volatile file ids from the break notification
    with an open file but it skips all share besides the first one.
    Fix this by looking up in all shares belonging to the server that
    issued the oplock break.

    Cc: Stable
    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     
  • Helps distinguish between an interrupted close and a truly
    unmatched open.

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Ronnie Sahlberg
     
  • If Close command is interrupted before sending a request
    to the server the client ends up leaking an open file
    handle. This wastes server resources and can potentially
    block applications that try to remove the file or any
    directory containing this file.

    Fix this by putting the close command into a worker queue,
    so another thread retries it later.

    Cc: Stable
    Tested-by: Frank Sorenson
    Reviewed-by: Ronnie Sahlberg
    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     
  • The smb2/smb3 message checking code was logging to dmesg when mounting
    with encryption ("seal") for compounded SMB3 requests. When encrypted
    the whole frame (including potentially multiple compounds) is read
    so the length field is longer than in the case of non-encrypted
    case (where length field will match the the calculated length for
    the particular SMB3 request in the compound being validated).

    Avoids the warning on mount (with "seal"):

    "srv rsp padded more than expected. Length 384 not ..."

    Signed-off-by: Steve French

    Steve French
     

16 Apr, 2019

1 commit

  • In the oplock break handler, writing pending changes from pages puts
    the FileInfo handle. If the refcount reaches zero it closes the handle
    and waits for any oplock break handler to return, thus causing a deadlock.

    To prevent this situation:

    * We add a wait flag to cifsFileInfo_put() to decide whether we should
    wait for running/pending oplock break handlers

    * We keep an additionnal reference of the SMB FileInfo handle so that
    for the rest of the handler putting the handle won't close it.
    - The ref is bumped everytime we queue the handler via the
    cifs_queue_oplock_break() helper.
    - The ref is decremented at the end of the handler

    This bug was triggered by xfstest 464.

    Also important fix to address the various reports of
    oops in smb2_push_mandatory_locks

    Signed-off-by: Aurelien Aptel
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky
    CC: Stable

    Aurelien Aptel
     

05 Mar, 2019

2 commits

  • Currently on lease break the client sets a caching level twice:
    when oplock is detected and when oplock is processed. While the
    1st attempt sets the level to the value provided by the server,
    the 2nd one resets the level to None unconditionally.
    This happens because the oplock/lease processing code was changed
    to avoid races between page cache flushes and oplock breaks.
    The commit c11f1df5003d534 ("cifs: Wait for writebacks to complete
    before attempting write.") fixed the races for oplocks but didn't
    apply the same changes for leases resulting in overwriting the
    server granted value to None. Fix this by properly processing
    lease breaks.

    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French
    CC: Stable

    Pavel Shilovsky
     
  • We should add any credits granted to us from unmatched server responses.

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky

    Ronnie Sahlberg
     

25 Jan, 2019

1 commit


03 Sep, 2018

1 commit

  • I ran into some cases where server was returning the wrong length
    on frames but I couldn't easily match them to the command in the
    network trace (or server logs) since I need the command and/or
    multiplex id to find the offending SMB2/SMB3 command. Add these
    two fields to the log message. In the case of padding too much
    it may not be a problem in all cases but might have correlated
    to a network disconnect case in some problems we have been
    looking at. In the case of frame too short is even more important.

    Signed-off-by: Steve French
    Reviewed-by: Ronnie Sahlberg

    Steve French
     

24 Aug, 2018

1 commit

  • Some SMB2/3 servers, Win2016 but possibly others too, adds padding
    not only between PDUs in a compound but also to the final PDU.
    This padding extends the PDU to a multiple of 8 bytes.

    Check if the unexpected length looks like this might be the case
    and avoid triggering the log messages for :

    "SMB2 server sent bad RFC1001 len %d not %d\n"

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Ronnie Sahlberg
     

08 Aug, 2018

1 commit

  • 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
    Acked-by: Aurelien Aptel
    Reviewed-by: Ronnie Sahlberg

    Steve French
     

15 Jun, 2018

2 commits


07 Jun, 2018

1 commit

  • cifs->master_tlink is NULL against Win Server 2016 (which is
    strange.. not sure why) and is dereferenced in cifs_sb_master_tcon().

    move master_tlink getter to cifsglob.h so it can be used from
    smb2misc.c

    Signed-off-by: Aurelien Aptel
    Reviewed-by: Ronnie Sahlberg
    Signed-off-by: Steve French
    Acked-by: Pavel Shilovsky

    Aurelien Aptel
     

03 Jun, 2018

1 commit


01 Jun, 2018

6 commits


31 May, 2018

1 commit


28 May, 2018

1 commit


13 Apr, 2018

2 commits

  • More cleanup of use of hardcoded 4 byte RFC1001 field size

    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky
    Reviewed-by: Ronnie Sahlberg

    Steve French
     
  • The length checking for SMB3.11 negotiate request includes
    "negotiate contexts" which caused a buffer validation problem
    and a confusing warning message on SMB3.11 mount e.g.:

    SMB2 server sent bad RFC1001 len 236 not 170

    Fix the length checking for SMB3.11 negotiate to account for
    the new negotiate context so that we don't log a warning on
    SMB3.11 mount by default but do log warnings if lengths returned
    by the server are incorrect.

    CC: Stable
    Signed-off-by: Steve French
    Reviewed-by: Aurelien Aptel
    Reviewed-by: Pavel Shilovsky

    Steve French
     

03 Apr, 2018

2 commits


02 Apr, 2018

1 commit

  • 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
    Signed-off-by: Steve French
    CC: Stable
    Reviewed-by: Ronnie Sahlberg

    Aurelien Aptel
     

25 Jan, 2018

1 commit


03 May, 2017

1 commit

  • When the final cifsFileInfo_put() is called from cifsiod and an oplock
    break work is queued, lockdep complains loudly:

    =============================================
    [ INFO: possible recursive locking detected ]
    4.11.0+ #21 Not tainted
    ---------------------------------------------
    kworker/0:2/78 is trying to acquire lock:
    ("cifsiod"){++++.+}, at: flush_work+0x215/0x350

    but task is already holding lock:
    ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0

    other info that might help us debug this:
    Possible unsafe locking scenario:

    CPU0
    ----
    lock("cifsiod");
    lock("cifsiod");

    *** DEADLOCK ***

    May be due to missing lock nesting notation

    2 locks held by kworker/0:2/78:
    #0: ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0
    #1: ((&wdata->work)){+.+...}, at: process_one_work+0x255/0x8e0

    stack backtrace:
    CPU: 0 PID: 78 Comm: kworker/0:2 Not tainted 4.11.0+ #21
    Workqueue: cifsiod cifs_writev_complete
    Call Trace:
    dump_stack+0x85/0xc2
    __lock_acquire+0x17dd/0x2260
    ? match_held_lock+0x20/0x2b0
    ? trace_hardirqs_off_caller+0x86/0x130
    ? mark_lock+0xa6/0x920
    lock_acquire+0xcc/0x260
    ? lock_acquire+0xcc/0x260
    ? flush_work+0x215/0x350
    flush_work+0x236/0x350
    ? flush_work+0x215/0x350
    ? destroy_worker+0x170/0x170
    __cancel_work_timer+0x17d/0x210
    ? ___preempt_schedule+0x16/0x18
    cancel_work_sync+0x10/0x20
    cifsFileInfo_put+0x338/0x7f0
    cifs_writedata_release+0x2a/0x40
    ? cifs_writedata_release+0x2a/0x40
    cifs_writev_complete+0x29d/0x850
    ? preempt_count_sub+0x18/0xd0
    process_one_work+0x304/0x8e0
    worker_thread+0x9b/0x6a0
    kthread+0x1b2/0x200
    ? process_one_work+0x8e0/0x8e0
    ? kthread_create_on_node+0x40/0x40
    ret_from_fork+0x31/0x40

    This is a real warning. Since the oplock is queued on the same
    workqueue this can deadlock if there is only one worker thread active
    for the workqueue (which will be the case during memory pressure when
    the rescuer thread is handling it).

    Furthermore, there is at least one other kind of hang possible due to
    the oplock break handling if there is only worker. (This can be
    reproduced without introducing memory pressure by having passing 1 for
    the max_active parameter of cifsiod.) cifs_oplock_break() can wait
    indefintely in the filemap_fdatawait() while the cifs_writev_complete()
    work is blocked:

    sysrq: SysRq : Show Blocked State
    task PC stack pid father
    kworker/0:1 D 0 16 2 0x00000000
    Workqueue: cifsiod cifs_oplock_break
    Call Trace:
    __schedule+0x562/0xf40
    ? mark_held_locks+0x4a/0xb0
    schedule+0x57/0xe0
    io_schedule+0x21/0x50
    wait_on_page_bit+0x143/0x190
    ? add_to_page_cache_lru+0x150/0x150
    __filemap_fdatawait_range+0x134/0x190
    ? do_writepages+0x51/0x70
    filemap_fdatawait_range+0x14/0x30
    filemap_fdatawait+0x3b/0x40
    cifs_oplock_break+0x651/0x710
    ? preempt_count_sub+0x18/0xd0
    process_one_work+0x304/0x8e0
    worker_thread+0x9b/0x6a0
    kthread+0x1b2/0x200
    ? process_one_work+0x8e0/0x8e0
    ? kthread_create_on_node+0x40/0x40
    ret_from_fork+0x31/0x40
    dd D 0 683 171 0x00000000
    Call Trace:
    __schedule+0x562/0xf40
    ? mark_held_locks+0x29/0xb0
    schedule+0x57/0xe0
    io_schedule+0x21/0x50
    wait_on_page_bit+0x143/0x190
    ? add_to_page_cache_lru+0x150/0x150
    __filemap_fdatawait_range+0x134/0x190
    ? do_writepages+0x51/0x70
    filemap_fdatawait_range+0x14/0x30
    filemap_fdatawait+0x3b/0x40
    filemap_write_and_wait+0x4e/0x70
    cifs_flush+0x6a/0xb0
    filp_close+0x52/0xa0
    __close_fd+0xdc/0x150
    SyS_close+0x33/0x60
    entry_SYSCALL_64_fastpath+0x1f/0xbe

    Showing all locks held in the system:
    2 locks held by kworker/0:1/16:
    #0: ("cifsiod"){.+.+.+}, at: process_one_work+0x255/0x8e0
    #1: ((&cfile->oplock_break)){+.+.+.}, at: process_one_work+0x255/0x8e0

    Showing busy workqueues and worker pools:
    workqueue cifsiod: flags=0xc
    pwq 0: cpus=0 node=0 flags=0x0 nice=0 active=1/1
    in-flight: 16:cifs_oplock_break
    delayed: cifs_writev_complete, cifs_echo_request
    pool 0: cpus=0 node=0 flags=0x0 nice=0 hung=0s workers=3 idle: 750 3

    Fix these problems by creating a a new workqueue (with a rescuer) for
    the oplock break work.

    Signed-off-by: Rabin Vincent
    Signed-off-by: Steve French
    CC: Stable

    Rabin Vincent
     

07 Apr, 2017

1 commit

  • 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
    Reviewed-by: Pavel Shilovsky
    Cc: Stable

    Sachin Prabhu
     

02 Feb, 2017

1 commit

  • In order to support compounding and encryption we need to separate
    RFC1001 length field and SMB2 header structure because the protocol
    treats them differently. This change will allow to simplify parsing
    of such complex SMB2 packets further.

    Signed-off-by: Pavel Shilovsky

    Pavel Shilovsky