Re: [PATCH v4 0/2] cifs: fix readdir stale size bug and deferred-close reference leak

Steve French <[email protected]> Tue, 21 Jul 2026 20:28:24 -0500
Newsgroups org.kernel.vger.linux-cifs
Message-ID <CAH2r5murna29cwOYicOf-=-QPBDssgbwu8sYyogGTe_TS40d0g@mail.gmail.com>
tentatively merged into cifs-2.6.git for-next pending more reviews and testing

On Tue, Jul 21, 2026 at 7:16 PM Frank Sorenson <[email protected]> wrote:
>
> This series fixes two bugs in the cifs/smb3 client: a race where
> readdir overwrites cached file sizes with stale server directory
> metadata, and a pre-existing reference leak in the deferred-close
> drain paths.
>
> Patch 1 fixes a bug where stat() returns the wrong file size after a
> write+close or rename against Windows Server.  Windows Server's directory
> enumeration metadata (EndOfFile) lags behind the actual file state
> immediately after a modification.  If a concurrent readdir() runs during
> that lag, it overwrites the correctly cached i_size with the stale server
> value; a subsequent stat() within the actimeo window then returns the
> wrong size.  Both the write+close and rename cases share the same root
> cause.  The bug does not reproduce against Samba or with actimeo=0.
>
> The fix adds cifsInodeInfo->time_last_write, stamped at writable close
> and at truncate.  is_size_safe_to_change() blocks readdir from updating
> i_size within acregmax jiffies of that timestamp.  When a size update is
> blocked and the server value differs from the cached one, the attribute
> cache is invalidated, forcing a fresh QUERY_INFO on the next stat().
> time_last_write is refreshed at the actual server close in
> smb2_deferred_work_close() and the cifs_close_deferred_file*() drain
> paths to ensure the protection window is anchored to the real close time
> when closetimeo > 0.
>
> Testing
> -------
> Reproduces against Windows Server 2022 with SMB 3.1.1 with multiple
> concurrent threads; does not reproduce against Samba or with actimeo=0.
> A reproducer exercising concurrent write+close+stat and rename+stat with
> concurrent readdir was run for 50,000+ iterations without hitting the bug.
>
> A reproducer is available at https://github.com/fsorenson/cifs_cache_race_repro/
>
>
> Patch 2 addresses a pre-existing reference leak in the deferred-close
> drain paths; when cancel_delayed_work() succeeds but the subsequent
> kmalloc_obj() for the processing list fails, the cancelled work's
> cifsFileInfo reference is silently dropped without calling
> _cifsFileInfo_put(), leaking the reference and the open server handle.
>
> The fix saves the affected cfile and calls _cifsFileInfo_put() after
> releasing the lock.
>
>
> v4: add memory barrier comments required by checkpatch; fix pre-existing
>     cifsFileInfo reference leak on kmalloc failure in deferred-close
>     drain paths (patch 2)
> v3: replace CIFS_INO_LOCK serialization approach with time_last_write
>     tracking; single patch covered both observed symptoms
> v2: fix malformed patch
>
> Frank Sorenson (2):
>   cifs: prevent readdir from changing file size due to stale directory metadata
>   cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain paths
>
>  fs/smb/client/cifsfs.c   |  1 +
>  fs/smb/client/cifsglob.h |  1 +
>  fs/smb/client/file.c     | 69 +++++++++++++++++++++++++++++++++++++++++++----
>  fs/smb/client/inode.c    |  6 ++++
>  fs/smb/client/misc.c     | 72 +++++++++++++++++++++++++++++++++++++++++++------
>  5 files changed, 135 insertions(+), 14 deletions(-)
>
> --
> 2.55.0
>
>


-- 
Thanks,

Steve