Commit graph

2,527 commits

Author SHA1 Message Date
Linus Torvalds
ce14fe4cd7 There are thirty-three client fixes:
- five sensitive data leak fixes (clear stack and heap cryptographic
   keys/hashes)
 - six file size and cache synchronization fixes (fscache cookie
   serialization and truncation handling)
 - seven protocol validation and buffer safety fixes (prevent OOB
   access and loff_t underflow)
 - six metadata and POSIX attribute fixes (proper hard-link counts and
   setuid/setgid stripping)
 - three DFS cache and unmount fixes (prevent target-hint UAF and
   unmount hangs)
 - six general client improvements (fix read request leaks, stats
   loops, handle servers that don't support O_TMPFILE)
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTcqRusfSdYROJQwGkpVtNKoQNdYwUCaoy9dgAKCRApVtNKoQNd
 Y5zrAP9HRp0z9rLmezHzGoTnF+0WYnkE9xK9pqRDoIjflXPyDAD+IDYzBXTWJpoq
 O1+3OiuNGvoF+X46i8xE9voAbnCTDgM=
 =ETzr
 -----END PGP SIGNATURE-----

Merge tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linux

Pull smb client updates from Paulo Alcantara:

 - clear sensitive data after use (stack and heap cryptographic
   keys/hashes)

 - file size and cache synchronization fixes (fscache cookie
   serialization and truncation handling)

 - protocol validation and buffer safety fixes (prevent OOB access and
   loff_t underflow)

 - metadata and POSIX attribute fixes (proper hard-link counts and
   setuid/setgid stripping)

 - DFS cache and unmount fixes (prevent target-hint UAF and unmount
   hangs)

 - general client improvements (fix read request leaks, stats loops,
   handle servers that don't support O_TMPFILE)

* tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linux: (33 commits)
  cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0
  smb: client: reject a tree connect response whose byte count is too small
  cifs: call pagecache_isize_extended() in cifs_setsize() when extending
  smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV
  smb: client: remove redundant NULL check before kfree()
  smb: client: restore the data_offset bound in is_valid_oplock_break()
  cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()
  smb: client: Avoid leaking sensitive data to the heap in connect.c
  smb: client: Clear sensitive stack data in smb1encrypt.c
  smb: client: Clear sensitive stack data in cifsencrypt.c
  smb: client: Clear sensitive stack and heap data in smb2ops.c
  smb: client: Clear sensitive stack data in smb2transport.c
  Revert "cifs: remove all cifs files before kill super"
  smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()
  smb: client: fix ALIGN() overflow in symlink_data() error context loop
  smb: client: simplify __build_path_from_dentry_optional_prefix()
  smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2
  smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
  smb/client: decode reparse metadata using its payload type
  smb/client: preserve open info type across compound queries
  ...
2026-08-24 18:11:49 -07:00
Frank Sorenson
6c322f5cf7 cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0
With len == 0 (clone to EOF), the effective length is computed as:

    len = src_inode->i_size - off;

If off > i_size, this is a negative loff_t, corrupting the ByteCount
in the FSCTL_DUPLICATE_EXTENTS_TO_FILE request and inverting the range
in filemap_write_and_wait_range().  The existing off >= i_size check
fires only after the ioctl has already been sent.

Snapshot i_size_read() once for both the bounds check and the length
calculation, eliminating the TOCTOU and 32-bit torn-read risk.  Reject
off > src_size with -EINVAL.  Treat off == src_size as a no-op,
consistent with __generic_remap_file_range_prep().

Fixes: 04b38d6012 ("vfs: pull btrfs clone API to vfs layer")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Bryam Vargas
65deb18359 smb: client: reject a tree connect response whose byte count is too small
CIFSTCon() bounds its strnlen() over the byte area with the server's
ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int
and converts to a huge size_t.  The later subtraction wraps the __u16
bytes_left, and that is what bounds cifs_strndup_from_utf16(): a bound of
up to 65535 against a ~16 KB cifs_req_poolp object runs off the end of the
slab object, and the bytes reach userspace through tcon->nativeFileSystem
in /proc/fs/cifs/DebugData.

Reject a byte area too small for what the parser consumes.  Two bytes is
the least it can consume, and no conformant response carries fewer.  The
new trace point is the 129th smb_eio_trace entry, which __mode(byte)
cannot represent, so the attribute goes with it.

Fixes: cc20c031bb ("cifs: convert CIFSTCon to use new unicode helper functions")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
c510edb973 cifs: call pagecache_isize_extended() in cifs_setsize() when extending
cifs_setsize() calls truncate_pagecache() but skips
pagecache_isize_extended() on extension.  truncate_setsize() shows
the correct pattern:

  i_size_write(inode, newsize);
  if (newsize > oldsize)
      pagecache_isize_extended(inode, oldsize, newsize);
  truncate_pagecache(inode, newsize);

pagecache_isize_extended() zeroes the tail of the page straddling old
EOF.  Without it, dirty bytes in that region can be written back to
the server, exposing stale data in the newly extended range.

Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
5d14030b46 smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV
The LXDEV block in cifs_query_path_info() uses SMB2_WSL_XATTR_MODE_SIZE
(4) instead of SMB2_WSL_XATTR_DEV_SIZE (8), undercounting eas_len by 4
bytes per $LXDEV EA.

eas_len is used only as a zero/non-zero presence flag so there is no
current functional impact, but the value is incorrect and misleading.

Fixes: 97db416045 ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Cc: stable@vger.kernel.org
Cc: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Mohammad Shahid
019716ca26 smb: client: remove redundant NULL check before kfree()
kfree() safely handles NULL pointers, so the explicit NULL check
before calling kfree() is unnecessary.

This issue was reported by ifnullfree.cocci.

Signed-off-by: Mohammad Shahid <mdshahid03@gmail.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Bryam Vargas
ba22f575de smb: client: restore the data_offset bound in is_valid_oplock_break()
Commit 83bfbd0bb9 ("cifs: Remove the RFC1002 header from smb_hdr")
changed the quantity this bound is measured against.  It used to be
srv->total_read minus the 4-byte RFC1002 preamble that total_read then
included, so it was the SMB message length.  The same commit stopped
counting the preamble, and the mechanical substitution to
srv->total_read - srv->pdu_size left an expression that is identically
zero: standard_receive3() reads MID_HEADER_SIZE() bytes and then exactly
pdu_length - MID_HEADER_SIZE() more, adding both to total_read.

len is therefore 0, the subtraction below it wraps, and no __u32
DataOffset can exceed the result, so the check from commit 097f5863b1
("cifs: read overflow in is_valid_oplock_break()") no longer rejects
anything.  Use total_read, which is now the message length on its own.

Fixes: 83bfbd0bb9 ("cifs: Remove the RFC1002 header from smb_hdr")
Cc: stable@kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
b96db32fed cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()
When the else branch of cifs_file_set_size() finds a writable file handle
via find_writable_file(), it borrows tcon and server from the handle's
tlink, attempts the handle-based set_file_size() RPC, and then releases
the handle with cifsFileInfo_put().

If set_file_size() fails, execution falls through to the path-based
fallback, which reuses the borrowed tcon and server under the
"if (tcon == NULL)" guard.  Since tcon is not NULL at that point, the
guard is skipped.  If cifsFileInfo_put() dropped the last reference on a
tlink that was already removed from the tlink tree (TCON_LINK_IN_TREE
cleared, as happens during reconnection or session teardown),
cifs_put_tlink() will have freed tcon; the subsequent set_path_size()
call is then a use-after-free.

Setting tcon = NULL after cifsFileInfo_put() causes the existing guard
to take the cifs_sb_tlink() path, which acquires a fresh reference for
the path-based operation or fails cleanly if the session is gone.

Fixes: 110fee6b9b ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc: stable@vger.kernel.org
Cc: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Thomas Huth
111a2b8717 smb: client: Avoid leaking sensitive data to the heap in connect.c
TCP_Server_Info contains a preauth_sha_hash[] and a cryptkey[] array
that might contain sensitive data. Thus free its memory with
kfree_sensitive() to avoid that we are leaking this information to
the heap.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Thomas Huth
2f9af06e30 smb: client: Clear sensitive stack data in smb1encrypt.c
Make sure to not leak signature data via the stack, clear it
with memzero_explicit() before leaving the function.

To avoid that we have to introduce "goto"-cleanup here, we re-arrange
the code a little bit (and drop the commented cifs_dump_mem debug
code that looks like a leftover from very early days).

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Thomas Huth
1a6bd74a27 smb: client: Clear sensitive stack data in cifsencrypt.c
Make sure to not leak hash data via the stack, clear it
with memzero_explicit() before leaving the function.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Thomas Huth
55a1ad8413 smb: client: Clear sensitive stack and heap data in smb2ops.c
Make sure to not leak key-related data via the heap or the stack
by using kfree_sensitive() or memzero_explicit() here.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Thomas Huth
3d93986f68 smb: client: Clear sensitive stack data in smb2transport.c
Sensitive data like keys that are stored in stack-local arrays could
be leaked via the stack to the calling functions. There is no known
vulnerability for this right now, but it's good security style to
explicitly zeroize this sensitive material as soon as possible to
avoid that it could be exploited together with other bugs later.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Zizhi Wo
ce31ec06d3 Revert "cifs: remove all cifs files before kill super"
This reverts commit 6d9a4aaaa8.

First, directly flushing fileinfo_put_wq in that commit cannot guarantee
that all in-flight I/O has run its cleanup_work on system_dfl_wq and
subsequently called queue_work(fileinfo_put_wq, ...). Flushing only the
latter workqueue may therefore miss puts that have not yet been queued, so
the fix is not reliable in the first place. Moreover, this fix flushes
inside cifs_umount(), which means the busy-dentry warning can still be
triggered when umount_check() is called inside kill_anon_super(), because
kill_anon_super() is executed before cifs_umount().

Second, commit 75f5c412fa ("smb: client: fix busy dentry warning on
unmount after DIO") already drains both serverclose_wq and fileinfo_put_wq
in cifs_kill_sb(), before kill_anon_super(). By adding a per-superblock
outstanding-rreq counter, it guarantees that all cleanup_work for this sb
have run, and thus all relevant cfile puts are queued on fileinfo_put_wq
or serverclose_wq.

Third, no path between those drains and cifs_umount() can queue new work
onto either workqueue. In the "cifs_sb->root == NULL" path there are no
file-related workers either, so that case is safe as well.

Therefore the busy-dentry and null-ptr-deref problems cannot arise, and
the flush added by commit 6d9a4aaaa8 ("cifs: remove all cifs files before
kill super") is redundant and can be removed.

Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
05f78e6cf3 smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()
reparse_buf_ptr() reads buf->ReparseDataLength before checking that
count covers the full fixed header:

    buf = (struct reparse_data_buffer *)((u8 *)io + off);
    len = sizeof(*buf);                          /* 8 bytes */
    rdlen = le16_to_cpu(buf->ReparseDataLength); /* offset 4, 2 bytes */

    if (count < len || count < rdlen + len)      /* check comes after */

struct reparse_data_buffer has ReparseDataLength at offset 4.  If a
server returns OutputCount < 6, the read at offset 4-5 reaches past
the end of the received data.  The off+count bounds against iov_len
were already validated, but that does not protect against count being
smaller than sizeof(*buf).

Split the check: verify count >= sizeof(*buf) before reading
ReparseDataLength, then verify count covers the data region.

Fixes: a158bb66b1 ("smb: client: optimise reparse point querying")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
62656b024e smb: client: fix ALIGN() overflow in symlink_data() error context loop
The check added by commit 7d9a7f1f96 ("smb/client: fix possible
infinite loop and oob read in symlink_data()") compared the post-ALIGN
length against the remaining buffer, but ALIGN() itself can overflow:
for ErrorDataLength near UINT32_MAX (e.g. 0xFFFFFFF9), ALIGN(x, 8)
wraps to 0, so the subsequent bounds check passes, and the loop
advances by zero bytes leaving 'p' pointing into stale data.

Fix by checking the raw ErrorDataLength against the remaining space
before applying ALIGN(), then checking again after.  Since raw_len is
bounded by the buffer, raw_len + 7 cannot overflow, so the second check
is an exact post-alignment bounds guard.

Fixes: 76894f3e2f ("cifs: improve symlink handling for smb2+")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Dmitry Antipov
3fffaa8a64 smb: client: simplify __build_path_from_dentry_optional_prefix()
Use the convenient 'strreplace()' to simplify
'__build_path_from_dentry_optional_prefix()'.

Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
730d0bb195 smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2
When a valid primary TRANSACT2 response has been received (mid->resp_buf
set, mid->multiRsp true) and a subsequent secondary response causes
cifs_check_trans2() to return false -- either because the SMB header is
invalid (malformed != 0) or because check2ndT2() rejects the PDU --
handle_mid() overwrites mid->resp_buf with the new buffer (leaking the
primary buffer) and, because mid->multiRsp is set, skips the
server->smallbuf/bigbuf NULL-out.  When the user thread frees
mid->resp_buf, server->smallbuf or server->bigbuf is left dangling; the
demux thread reuses it for the next packet, resulting in a use-after-free.

Combine both early-exit conditions and, when mid->multiRsp is already
set, abort the pending transaction inline: set multiEnd, call
dequeue_mid() with malformed=true, and return true so handle_mid() exits
without touching mid->resp_buf or the server buffer pointers.

Fixes: 316cf94a91 ("CIFS: Move trans2 processing to ops struct")
Cc: stable@vger.kernel.org # cifs_check_trans2() is in smb1ops.c on kernels < 7.0
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Frank Sorenson
6343c1da56 smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
coalesce_t2() computes data pointers directly from server-supplied
DataOffset fields with no validation against buffer bounds:

  data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
                     get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
  data_area_of_src = (char *)&pSMBs->hdr.Protocol +
                     get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
  data_area_of_tgt += total_in_tgt;
  ...
  memcpy(data_area_of_tgt, data_area_of_src, total_in_src);

A small DataOffset can push a pointer below the actual byte area,
overwriting header fields; a large one can push it past the buffer
end, causing out-of-bounds heap reads (source) or writes (target).
The BCC overflow guard does not prevent this: BCC reflects how much
data is present, while DataOffset controls where in the buffer it
starts.

The "validate target area" comment present since the function was
first written in 2005 was a placeholder that was never implemented.

Add lower- and upper-bound checks for both data pointers before the
memcpy, and before any target header fields are modified.

Fixes: e4eb295d38 ("[PATCH] cifs: Handle multiple response transact2 part 1 of 2")
Cc: stable@vger.kernel.org
Reported-by: Shen Yongchao <grayhat@foxmail.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Ze Tan
43549eb842 smb/client: decode reparse metadata using its payload type
cifs_open_info_data stores FILE_ALL_INFORMATION and SMB3 POSIX query
information in a union. reparse_info_to_fattr() selects a union member
from the mount mode, while several directory checks always read
fi.Attributes.

The metadata can instead come from an SMB2 CREATE response on a POSIX
mount, or from a POSIX query while processing a reparse point. In those
cases the mount mode and hard-coded fi accesses select the wrong union
member.

See the procedures below:

  cifs_nt_open
    smb2_open_file
      SMB2_open
        data->fi = SMB2 CREATE response
        data->contains_posix_file_info = false
    cifs_get_inode_info
      reparse_info_to_fattr
        if (tcon->posix_extensions) // true
          smb311_posix_info_to_fattr
            data->posix_fi // wrong union member

  smb311_posix_get_fattr
    smb2_query_path_info
      smb2_compound_op
        data->posix_fi = SMB3 POSIX query response
        data->contains_posix_file_info = true
    reparse_info_to_fattr
      data->fi.Attributes // wrong union member

Add a common DOS attribute accessor and use contains_posix_file_info
both for attribute reads and for the final fattr conversion.

Signed-off-by: Ze Tan <tanze@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:53 -03:00
Ze Tan
9437f2113b smb/client: preserve open info type across compound queries
contains_posix_file_info describes the metadata stored in the
fi/posix_fi union. GET_REPARSE and QUERY_WSL_EA do not update that
union, so clearing the flag while processing those responses can make
POSIX metadata look like FILE_ALL_INFORMATION.

Set the flag when CREATE or a validated query response actually
populates the union, and leave it unchanged for auxiliary compound
operations. This also avoids changing the type when a query fails
before copying any metadata.

The issue can be reproduced against a Samba server with SMB3 UNIX
extensions enabled:

  mount -t cifs //<server>/<share> /mnt/cifs \
        -o vers=3.1.1,posix,reparse=nfs,actimeo=0
  mkfifo /mnt/cifs/test-fifo
  umount /mnt/cifs
  mount -t cifs //<server>/<share> /mnt/cifs \
        -o vers=3.1.1,posix,reparse=nfs,actimeo=0
  stat -c '%F %s' /mnt/cifs/test-fifo

Before this change, stat reports "fifo 1024" although the server-side
EOF is zero. After this change, it reports "fifo 0".

Fixes: 9df23801c8 ("smb311: failure to open files of length 1040 when mounting with SMB3.1.1 POSIX extensions")
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:52 -03:00
Ze Tan
ebdc1afb1e smb/client: mark missing nlink values as unknown
Several SMB1 fallback and open responses do not provide the hard link
count. The SMB2 create-only query fallback has the same limitation.
These paths currently leave a zero link count or synthesize a value of
one and then expose it as authoritative metadata.

Mark those results with unknown_nlink so existing inodes keep their
cached link count and new inodes receive the usual sane default.

This was tested against Samba with "server min protocol = NT1". Mount
the share using SMB1 with Unix extensions disabled:

  mount -t cifs //<server>/<share> /mnt/cifs \
        -o username=<user>,vers=1.0,nounix

Create three names for the same inode and cache its real link count:

  TESTDIR=/mnt/cifs/nlink-repro-$$
  mkdir "$TESTDIR"
  touch "$TESTDIR/file1"
  ln "$TESTDIR/file1" "$TESTDIR/file2"
  ln "$TESTDIR/file1" "$TESTDIR/file3"
  stat -c 'before open: %h' "$TESTDIR/file1"

Open the file and read the link count through the open descriptor:

  exec 3<"$TESTDIR/file1"
  stat -Lc 'after open: %h' /proc/$$/fd/3
  exec 3<&-

Clean up the test files:

  rm -f "$TESTDIR/file1" "$TESTDIR/file2" "$TESTDIR/file3"
  rmdir "$TESTDIR"

Before this change, the two stat commands report 3 and 1 because the
SMB1 open response overwrites the known link count. With this change,
both commands report 3.

Signed-off-by: Ze Tan <tanze@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:52 -03:00
Frank Sorenson
48cab1fd57 cifs: fix clearing stats for fastest execution of each smb2 command
The code to clear the 'fastest_cmd' statistics has a typo that
repeatedly clears the stat for cmd 0, rather than iterating
through each cmd.  Fix the typo (0->i).

Fixes: 433b8dd767 ("SMB3: Track total time spent on roundtrips for each SMB3 command")
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24 17:08:52 -03:00
Linus Torvalds
61a09cfc12 This contains a set of 142 SMB server updates focused on SMB2 command
sequencing, SMB3 request replay and encryption, Apple Time Machine
 interoperability, protocol-compatibility fixes validated with smbtorture,
 security hardening, SMB Direct transport support, connection reliability,
 and other correctness improvements.
 
 New features:
 
  - Implement the SMB2 command sequence window.
    Enforce the credit-based MessageId range for each connection, rejecting
    out-of-window, duplicate, and wrapped sequence numbers. This prevents
    invalid requests and same-channel replays from being processed.
 
  - Add SMB3 request replay support.
    SMB3 clients may resend requests with SMB2_FLAGS_REPLAY_OPERATION after
    a channel disconnect when the original response was lost. Track the
    required channel and open state to safely handle durable CREATE replays
    and make oplock, lease, and lock replays idempotent, avoiding duplicate
    state changes and improving multichannel reconnect reliability.
 
  - Add opt-in Apple Time Machine support.
    Implement the AAPL negotiation and related Finder, stream, COPYCHUNK,
    sparse-file, CHANGE_NOTIFY, and RPC compatibility required for Time
    Machine shares, allowing macOS backupd to use ksmbd for backups.
 
  - Add per-share SMB3 encryption support.
    Allow individual shares to require SMB3 encryption by advertising
    SMB2_SHAREFLAG_ENCRYPT_DATA in TREE_CONNECT responses and rejecting
    unencrypted tree connects and plaintext requests for protected shares.
 
  - Add SMB Direct RDMA encryption support.
    Extend SMB Direct to support SMB3 encrypted payloads over RDMA, with
    transform negotiation and encryption/decryption for RDMA READ/WRITE.
 
 Other changes:
 
  - Parse and retain AppInstanceVersion contexts, enforce version ordering,
    close older active handles for newer takeovers, and reject invalid or
    unversioned opens according to the SMB2 semantics.
 
  - Accept durable reconnect requests that omit VolatileFileId when the
    persistent ID and reconnect context identify the handle, while
    continuing to reject explicit volatile-ID mismatches.
 
  - Fix SMB2/SMB3 protocol validation and security issues, including request
    offsets, file and object IDs, IPC responses, output buffer sizes,
    SMB3.1.1 binding validation, signing-required handling, durable handles,
    ACLs, maximal access, and security information.
 
  - Fix heap out-of-bounds accesses, use-after-free bugs, memory leaks,
    invalid pointer dereferences, and sensitive-data lifetime issues in
    authentication, Kerberos, preauthentication, sessions, connections,
    and module teardown.
 
  - Correct alternate-data-stream and named-stream handling, COPYCHUNK
    behavior, sparse-file and compression attributes, allocated-range
    queries, file trimming, duplicate extents, DOS attributes, snapshots,
    normalized names, and partial information responses.
 
  - Fix locking, lease, oplock, durable reconnect, async request, and
    CHANGE_NOTIFY races, including deferred-lock rollback, parent directory
    lease notifications, and connection teardown lifetime bugs.
 
  - Fix SMB3 encryption handling for compressed requests, expired encrypted
    sessions, interim responses, bound multichannel connections, and
    decryption failures.
 
  - Fix SMB3 multichannel session lookup and session state transitions so
    changes are scoped to the correct bound connections and cannot revive
    connections that are already shutting down.
 
  - Fix DACL access checks so ACE walks are bounded by the declared DACL
    size, preventing data beyond the DACL boundary from being interpreted
    during access validation.
 
  - Fix session accounting and lifetime issues, including session counter
    updates during publication and removal, session leaks on registration
    failure, and procfs creation diagnostics.
 
  - Improve TCP connection reliability by enabling TCP keepalive for
    accepted connections and preserving TCP timers for kernel sockets,
    preventing silent peers from holding connections indefinitely.
 
  - Fix smbdirect RDMA cleanup ordering for completion queues, QPs, child
    sockets, and listener locking.
 
  - Improve async response framing, multi-iovec signing, RPC pipe status
    handling, and ksmbd procfs monitoring for server, share, connection,
    session, and open-file state.
 
  - Remove the obsolete DES crypto header and Kconfig dependency now that
    NTLMv1 support has been removed.
 
  - Update the ksmbd repository URL in MAINTAINERS and add an additional
    KSMBD reviewer.
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqKrvwWHGxpbmtpbmpl
 b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCExxEACUk9E89TrgHUlSni/U4WEcg95n
 YNVm+oeRNnpqu7axGtIqmzgc7eU96ofR8un0pNLjkdWSD27hv6bmUv0e2+uOI7LU
 04FIwJfOLPR4roKgwyLhC+I88zjHWBxU2fAx1l0ksFpTAF4vFuo2Il/TsaM57QEm
 qhE0laiLV95jrtafnW8l2E+Be+qsRy7wRrj69IThfBBpwEMvehL3JK42yDItLKUm
 ETKJuO4O3QCN1tyMlntzshdLhuFIWrnNspTwKqMEE9/Ba4cuzGrcm6Y4tLDHDX/j
 Vr45w6rFsULJhw2mSz8cRYV3HcrPea7CVynJVDYtdIAngez0O3iLE5qAM1gff0HG
 5H4N57ye3iabySD9B9Hy8ISqreCGW7dNZf3LACmZyeXjNGmxGB4nrgTc9fz1SAcl
 JizpgMxrh2xj0YmABShgfqHFn9u+QvWaMIDYUddIQ+fX1Y+TxHDPssGJ0ygXCyJ0
 BrIwqRHgL7XONY2sx8bPWExAzVZq/4gPWVZACM7X138iuR1kDIEpnPqvMMpPx8am
 x5jSgvQ8NdABxLUZWU3BhcJseGG4gbvq0HzYibR6MPNy6P5ct3q+ifiWuY/JZ8Op
 ZTxcyShSXziy8uk7iKvGgS3eJ5bDSb2Wo9flkvoCifG7VgPfDec3d/V4f1n9cTix
 2TpmzQRF98f6arzzSQ==
 =uocO
 -----END PGP SIGNATURE-----

Merge tag 'ksmbd-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb

Pull smb server updates from Namjae Jeon:
 "This contains server updates focused on SMB2 command sequencing, SMB3
  request replay and encryption, Apple Time Machine interoperability,
  protocol-compatibility fixes validated with smbtorture, security
  hardening, SMB Direct transport support, connection reliability, and
  other correctness improvements.

  New features:

   - Implement the SMB2 command sequence window

     Enforce the credit-based MessageId range for each connection,
     rejecting out-of-window, duplicate, and wrapped sequence numbers.
     This prevents invalid requests and same-channel replays from being
     processed

   - Add SMB3 request replay support

     SMB3 clients may resend requests with SMB2_FLAGS_REPLAY_OPERATION
     after a channel disconnect when the original response was lost.
     Track the required channel and open state to safely handle durable
     CREATE replays and make oplock, lease, and lock replays idempotent,
     avoiding duplicate state changes and improving multichannel
     reconnect reliability

   - Add opt-in Apple Time Machine support

     Implement the AAPL negotiation and related Finder, stream,
     COPYCHUNK, sparse-file, CHANGE_NOTIFY, and RPC compatibility
     required for Time Machine shares, allowing macOS backupd to use
     ksmbd for backups

   - Add per-share SMB3 encryption support

     Allow individual shares to require SMB3 encryption by advertising
     SMB2_SHAREFLAG_ENCRYPT_DATA in TREE_CONNECT responses and rejecting
     unencrypted tree connects and plaintext requests for protected
     shares

   - Add SMB Direct RDMA encryption support

     Extend SMB Direct to support SMB3 encrypted payloads over RDMA,
     with transform negotiation and encryption/decryption for RDMA
     READ/WRITE

  Other changes:

   - Parse and retain AppInstanceVersion contexts, enforce version
     ordering, close older active handles for newer takeovers, and
     reject invalid or unversioned opens according to the SMB2 semantics

   - Accept durable reconnect requests that omit VolatileFileId when the
     persistent ID and reconnect context identify the handle, while
     continuing to reject explicit volatile-ID mismatches

   - Fix SMB2/SMB3 protocol validation and security issues, including
     request offsets, file and object IDs, IPC responses, output buffer
     sizes, SMB3.1.1 binding validation, signing-required handling,
     durable handles, ACLs, maximal access, and security information

   - Fix heap out-of-bounds accesses, use-after-free bugs, memory leaks,
     invalid pointer dereferences, and sensitive-data lifetime issues in
     authentication, Kerberos, preauthentication, sessions, connections,
     and module teardown

   - Correct alternate-data-stream and named-stream handling, COPYCHUNK
     behavior, sparse-file and compression attributes, allocated-range
     queries, file trimming, duplicate extents, DOS attributes,
     snapshots, normalized names, and partial information responses

   - Fix locking, lease, oplock, durable reconnect, async request, and
     CHANGE_NOTIFY races, including deferred-lock rollback, parent
     directory lease notifications, and connection teardown lifetime
     bugs

   - Fix SMB3 encryption handling for compressed requests, expired
     encrypted sessions, interim responses, bound multichannel
     connections, and decryption failures

   - Fix SMB3 multichannel session lookup and session state transitions
     so changes are scoped to the correct bound connections and cannot
     revive connections that are already shutting down

   - Fix DACL access checks so ACE walks are bounded by the declared
     DACL size, preventing data beyond the DACL boundary from being
     interpreted during access validation

   - Fix session accounting and lifetime issues, including session
     counter updates during publication and removal, session leaks on
     registration failure, and procfs creation diagnostics

   - Improve TCP connection reliability by enabling TCP keepalive for
     accepted connections and preserving TCP timers for kernel sockets,
     preventing silent peers from holding connections indefinitely

   - Fix smbdirect RDMA cleanup ordering for completion queues, QPs,
     child sockets, and listener locking

   - Improve async response framing, multi-iovec signing, RPC pipe
     status handling, and ksmbd procfs monitoring for server, share,
     connection, session, and open-file state

   - Remove the obsolete DES crypto header and Kconfig dependency now
     that NTLMv1 support has been removed

   - Update the ksmbd repository URL in MAINTAINERS and add an
     additional KSMBD reviewer"

* tag 'ksmbd-for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb: (142 commits)
  MAINTAINERS: update ksmbd repository URL
  MAINTAINERS: add myself as KSMBD reviewer
  smb: server: remove unused DES crypto header
  smb: server: Remove obsolete "select CRYPTO_LIB_DES" from Kconfig file
  ksmbd: keep TCP timers alive for kernel sockets
  ksmbd: enable TCP keepalive for accepted connections
  smb/server: fix session counter on session removal
  smb/server: update session counter under sessions table lock
  smb/server: fix session leak in ksmbd_session_register()
  smb/server: warn if ksmbd_proc_create() fails
  ksmbd: bound smb_check_perm_dacl() ACE walks by DACL size
  ksmbd: make RDMA encryption diagnostics conditional
  ksmbd: add SMB Direct RDMA encryption transform
  ksmbd: handle encrypted compressed requests
  ksmbd: decrypt requests from expired encrypted sessions
  ksmbd: disconnect on SMB3 decryption failure
  ksmbd: encrypt interim responses to encrypted requests
  ksmbd: scope session state changes to bound connections
  ksmbd: fix encrypted request lookup on bound channels
  ksmbd: add per-share SMB3 encryption enforcement
  ...
2026-08-23 08:41:36 -07:00
Linus Torvalds
21bd0802cd RDMA v7.3 merge window pull
Quite alot of buf fixes again:
 
 - Assorted locking, bounds-checking, cleanup, and error-path fixes across
   UCMA/CMA, bng_re, bnxt_re, cxgb4, EFA, ERDMA, HFI1, HNS, ionic, iRDMA,
   mlx4/mlx5, RXE, SIW, SRP/SRPT, and iSER target.
 
 - netlink report for max # of supported resources
 
 - get_zeroed_page()/etc removal
 
 - Robust udata for ionic
 
 - Allow unique RDMA device names per network namespace
 
 - Completion counters and v2 admit queue support for EFA
 
 - UC QP support for MANA
 
 - Completion timestamps for ionic
 
 - Harden uverbs data validation and resource lifetime handling, fixing several core use-after-free conditions.
 
 - bnxt_re toggle-page ownership and lifetime bug fixes
 
 - dmabuf SRQ support for mlx5
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCaoeO2wAKCRCFwuHvBreF
 YcyJAQCn8JeqTuayLchCARJX+9fazTaJES9zj41i3M8a7BfxCAEA2b266g0S660m
 7eQ761NiIb1iklSl9rmt8vM22EMcngM=
 =qcwp
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull RDMA updates from Jason Gunthorpe:
 "About the normal size, still a lot of AI bug fixes and so on, but some
  interesting new functionality too:

   - Assorted locking, bounds-checking, cleanup, and error-path fixes
     across UCMA/CMA, bng_re, bnxt_re, cxgb4, EFA, ERDMA, HFI1, HNS,
     ionic, iRDMA, mlx4/mlx5, RXE, SIW, SRP/SRPT, and iSER target.

   - netlink report for max # of supported resources

   - get_zeroed_page()/etc removal

   - Robust udata for ionic

   - Allow unique RDMA device names per network namespace

   - Completion counters and v2 admit queue support for EFA

   - UC QP support for MANA

   - Completion timestamps for ionic

   - Harden uverbs data validation and resource lifetime handling,
     fixing several core use-after-free conditions.

   - bnxt_re toggle-page ownership and lifetime bug fixes

   - dmabuf SRQ support for mlx5"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (160 commits)
  RDMA/ucma: Allow path records to exactly fit the output buffer
  RDMA/uverbs: Guard legacy bundles without method_elm
  RDMA/efa: Add support for 128B admin v2 SQ entry
  RDMA/efa: Generalize the admin SQ
  RDMA/efa: Decouple admin command payload from admin header
  RDMA/rxe: Fix OOB in free_rd_atomic_resources()
  RDMA/cma: Fix WARNING in res_to_rt
  RDMA/cxgb4: Free debugfs on registration failure
  RDMA/cxgb4: Cancel reg_work before freeing device on remove
  RDMA/ucma: Lock the handler in ucma_set_ib_path()
  RDMA/ucma: Lock the handler in ucma_write_cm_event()
  RDMA/erdma: restrict the driver to little-endian systems
  RDMA/ionic: Embed counter driver data in rdma_counter allocation
  RDMA/ionic: Cap eq_count to the eth driver's interrupt vector budget
  RDMA/siw: Fix use-after-free in siw_accept()
  IB/isert: post the full-feature receive buffers after session registration
  IB/isert: delay the final Login Response until the session is registered
  RDMA/srp: fix heap information leak on a truncated SRP_CRED_REQ
  RDMA/erdma: Hold QP references for AE and CM processing
  RDMA/erdma: Hold CQ references when processing EQ events
  ...
2026-08-21 11:48:54 -07:00
Namjae Jeon
c5e640fe34 smb: server: remove unused DES crypto header
The DES crypto header is no longer used after the removal of NTLMv1
authentication. Remove it now that the server no longer selects
CRYPTO_LIB_DES.

Fixes: ce812992f2 ("ksmbd: remove NTLMv1 authentication")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-20 22:56:15 +09:00
Thomas Huth
ed91d80242 smb: server: Remove obsolete "select CRYPTO_LIB_DES" from Kconfig file
The DES encryption in the smb server code has been removed in 2021
with the removal of the insecure NTLMv1 authentication code. Thus
we don't need this "select" statement here anymore.

Fixes: ce812992f2 ("ksmbd: remove NTLMv1 authentication")
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-20 22:56:13 +09:00
Namjae Jeon
80b6367ec3 ksmbd: keep TCP timers alive for kernel sockets
ksmbd creates its listening socket with sock_create_kern(). Kernel
sockets do not hold a network namespace reference by default. Accepted
sockets inherit this state.

When an accepted socket is released, tcp_close() clears its pending TCP
timers for a kernel socket after the socket enters an orphaned state. If
the peer is unreachable while ksmbd sends a FIN, this can leave a
FIN-WAIT-1 orphan without a retransmission timer.

Upgrade the listening socket's network namespace reference before
kernel_listen(). Accepted sockets inherit the reference, so the TCP
stack can keep the retransmission timer active and apply its normal
orphan retry policy.

Preserve the existing graceful shutdown behavior.

Link: https://github.com/openwrt/openwrt/issues/24744
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-20 22:56:12 +09:00
Namjae Jeon
56549c18a4 ksmbd: enable TCP keepalive for accepted connections
A client that disappears without sending a FIN or RST can leave its
ksmbd connection in ESTABLISHED indefinitely. ksmbd sets a socket
receive timeout, but the connection receive loop retries timeout errors
without a limit, so the connection remains in conn_list and consumes the
per-IP connection quota.

Enable SO_KEEPALIVE on accepted TCP sockets so the TCP stack can detect a
silent peer failure. The keepalive idle time, interval, and probe count
remain controlled by the existing TCP sysctl settings.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-20 22:56:10 +09:00
ChenXiaoSong
77d852c763 smb/client: fix nlink of an overwritten open file
Reproducer:

  1. server: systemctl start ksmbd
  2. client: mount with `posix` option
     mount -t cifs -o posix //${server_ip}/export /mnt
  3. client: touch /mnt/file1 /mnt/file2
  4. client: C program: int fd = open("/mnt/file2", O_RDONLY);
  5. client: C program: rename("/mnt/file1", "/mnt/file2");
  6. client: C program: struct stat stbuf; fstat(fd, &stbuf);
                        stbuf.st_nlink is 1, should be 0

This patch fixes xfstests generic/035 when mounted with `posix` option.

Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:57 -03:00
Frank Sorenson
60be95527b cifs: remove dead size-update blocks in cifs_setattr_unix/nounix
Commit 110fee6b9b ("smb: client: fix missing timestamp updates with
O_TRUNC") introduced cifs_file_set_size(), which calls netfs_resize_file()
and cifs_setsize() on success.  cifs_setsize() calls i_size_write(),
updating i_size to the new value.  The subsequent blocks in both
cifs_setattr_unix() and cifs_setattr_nounix():

    if ((attrs->ia_valid & ATTR_SIZE) &&
        attrs->ia_size != i_size_read(inode)) {
        truncate_setsize(inode, attrs->ia_size);
        netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true);
        fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size);
    }

are therefore unreachable on the success path: attrs->ia_size ==
i_size_read(inode) always holds after cifs_file_set_size() succeeds.
On the failure path, execution jumps to out/cifs_setattr_exit before
reaching these blocks.

truncate_setsize() and netfs_resize_file() are redundant with what
cifs_file_set_size() already did; fscache_resize_cookie() was moved there
by commit fa724e235c ("cifs: add fscache_resize_cookie() to
cifs_setsize()").  Remove both dead blocks.

Fixes: 110fee6b9b ("smb: client: fix missing timestamp updates with O_TRUNC")
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: Huiwen He <hehuiwen@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:53 -03:00
Frank Sorenson
297d8026a5 cifs: remove redundant size-update block in cifs_remap_file_range()
cifs_remap_file_range() acquires i_rwsem on both inodes via
lock_two_nondirectories() before calling smb2_duplicate_extents().
cifs_setsize() (called inside smb2_duplicate_extents() when the clone
extends the file) therefore already runs under the lock, meaning the
fscache_resize_cookie() added to cifs_setsize() by commit fa724e235c
("cifs: add fscache_resize_cookie() to cifs_setsize()") is correctly
serialised for this path without further changes.

That same commit made the caller-side block:

    if (rc == 0 && new_size > i_size) {
        truncate_setsize(target_inode, new_size);
        fscache_resize_cookie(cifs_inode_cookie(target_inode), new_size);
    }

redundant: smb2_duplicate_extents() already performs the full size update
via cifs_setsize() when the operation extends the file.  Remove the
now-dead block.

Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: Huiwen He <hehuiwen@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:45 -03:00
Frank Sorenson
32a7af68df cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
cifs_setsize() calls fscache_resize_cookie() without holding i_rwsem.
When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHING is set),
fscache_resize_cookie() performs a real resize that requires i_rwsem
held exclusively.  If another file descriptor has the same inode open,
fscache_use_cookie() was already called from that cifs_open(), making
the cookie active.  In that case, calling cifs_setsize() from
cifs_do_truncate() (invoked from cifs_open() without i_rwsem) races
against concurrent fscache I/O.

Strip fscache_resize_cookie() from cifs_setsize(), making it a pure
size/page-cache helper.  Add cifs_resize_file_locked() for callers
that already hold i_rwsem: it calls netfs_resize_file() and
cifs_setsize(), then temporarily activates the cookie with
fscache_use_cookie() to perform the resize under the lock, then
deactivates it with cifs_fscache_unuse_inode_cookie().  Using
fscache_use_cookie() before the resize ensures correctness whether or
not another fd already holds the cookie active.

Switch cifs_file_set_size(), smb2_duplicate_extents(), and both size-
extension branches of smb3_simple_falloc() to the new wrapper; those
paths already hold i_rwsem via VFS setattr, lock_two_nondirectories(),
or cifs_fallocate() respectively.  cifs_do_truncate() continues to
call cifs_setsize() followed by cifs_invalidate_cache(), since it runs
without i_rwsem.

Fixes: fa724e235c ("cifs: add fscache_resize_cookie() to cifs_setsize()")
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:36 -03:00
Frank Sorenson
364b183230 cifs: use cifs_invalidate_cache() in cifs_do_truncate() for O_TRUNC
cifs_do_truncate() is invoked from cifs_open() without i_rwsem, so it
cannot use cifs_resize_file_locked() to perform a proper fscache cookie
resize.  Instead, add cifs_invalidate_cache() after cifs_setsize().

cifs_invalidate_cache() calls fscache_invalidate(), which works without
holding i_rwsem: it unconditionally increments inval_counter and sets
FSCACHE_COOKIE_NO_DATA_TO_READ, ensuring that stale cached data is not
served once the cookie is later activated by fscache_use_cookie().
Truncation to zero leaves no valid cached data, making invalidation the
correct semantic here.

Fixes: fa724e235c ("cifs: add fscache_resize_cookie() to cifs_setsize()")
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:25 -03:00
Fredric Cover
b1b741cf8e smb: client: clear ce->tgthint in free_tgts()
When free_tgts() frees all structures in ce->tlist, ce->tgthint
is left pointing to one of the freed cache_dfs_tgt structures.

If ce->tgthint is not reset before it is used later, it results
in a use-after-free.

Set ce->tgthint to NULL in free_tgts() after the elements are
freed to reflect that no elements remain.

Fixes: 54be1f6c1c ("cifs: Add DFS cache routines")
Cc: stable@vger.kernel.org # depends on: smb: client: harden DFS cache against invalid target hints
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:22 -03:00
Fredric Cover
bf86c08123 smb: client: harden DFS cache against invalid target hints
Currently, get_tgt_name() returns ERR_PTR(-ENOENT) when ce->tgthint is
NULL, and dfs_cache_noreq_update_tgthint() assumes ce->tgthint is always
valid.

In preparation for clearing ce->tgthint in free_tgts(), harden callers
of get_tgt_name() against ERR_PTR results and harden
dfs_cache_noreq_update_tgthint() against NULL pointer dereferences.

Cc: stable@vger.kernel.org
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:19 -03:00
Jiangshan Yi
b8e5dc4f95 smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions
When a file has the setuid or setgid bit set and is written to, the VFS
strips those bits and issues a setattr with ATTR_KILL_SUID/ATTR_KILL_SGID
together with an ATTR_MODE carrying the already-cleared mode.

Both cifs_setattr_unix() and cifs_setattr_nounix() unconditionally dropped
ATTR_MODE in that case:

	/* skip mode change if it's just for clearing setuid/setgid */
	if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
		attrs->ia_valid &= ~ATTR_MODE;

This is fine for the default mount, where the mode is only emulated via
the DOS read-only attribute and cannot represent the setuid/setgid bits
anyway.  However, with the "cifsacl" or "modefromsid" mount options the
mode is stored on the server through an ACL (id_mode_to_cifs_acl()), with
the SMB3.1.1 POSIX extensions the mode is sent to the server directly,
and with the SMB1 Unix extensions (cifs_setattr_unix) the mode is sent
via CIFSSMBUnixSetPathInfo().  In all those cases dropping ATTR_MODE means
the cleared mode is never pushed to the server, so the setuid/setgid bit
survives the write.

This is a security issue: on local filesystems the setuid bit is stripped
when a file is written, but over these cifs.ko mounts the bit persists on
the server, potentially allowing an unexpected privilege escalation on
subsequent execution.

Fix this in two places:

  1. cifs_setattr_nounix(): only take the "skip mode change" shortcut
     when the mode is emulated via the DOS read-only attribute (i.e.
     neither cifsacl/modefromsid nor the SMB3.1.1 POSIX extensions are
     in effect), so that the cleared mode is propagated to the server
     in the ACL / POSIX cases.

  2. cifs_setattr_unix(): this function is only called when Unix
     extensions are in effect, so the mode is always stored on the
     server.  Remove the shortcut entirely so that the cleared mode is
     always pushed.

Fixes: d32c4f2626 ("CIFS: ignore mode change if it's just for clearing setuid/setgid bits")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:15 -03:00
Christopher Lusk
45f84cf25a smb: client: set replay flag on the read send-error retry path
smb2_async_readv() and smb2_async_writev() end with the same
send-error block: if the error is replayable and smb2_should_replay()
agrees, tell netfs to retry the subrequest. The write path also sets
wdata->replay. The read path does not set rdata->replay.

smb2_should_replay() is not a pure predicate. It consumes the retry
budget and computes the exponential back-off, doubling cur_sleep up to
CIFS_MAX_SLEEP. That back-off is only applied where the replay flag is
tested at the top of the reissued request:

	if (rdata->replay) {
		/* Back-off before retry */
		if (rdata->cur_sleep)
			msleep(rdata->cur_sleep);
		smb2_set_replay(server, &rqst);
	}

So on the read path the back-off is recomputed on every send-error
retry and then discarded, and SMB2_FLAGS_REPLAY_OPERATION is not set
on the reissued request.

netfs does not pace the retry either. netfs_reissue_read() calls
->issue_read() directly, and fs/netfs/read_retry.c contains no delay
of its own, so read send-error retries reissue immediately while the
equivalent write retries back off.

The read response callback already sets rdata->replay under the same
conditions, so the read path does use the replay mechanism. Only this
send-error path omits it.

Where the back-off belongs was settled while the commit below was
under review. David Howells asked whether netfslib should be doing the
back-off [1], and objected to sleeping inside the response callback
because that runs in the cifsd thread and would stall the socket [2].
The sleep was therefore taken out of smb2_should_replay() and moved to
just before the replay in smb2_async_readv() and smb2_async_writev()
[3]. Setting the flag here preserves that arrangement: the sleep still
happens at the top of the reissued request, not in a callback.

Set rdata->replay here, matching smb2_async_writev().

Fixes: 2c1238a747 ("cifs: make retry logic in read/write path consistent with other paths")
Link: https://lore.kernel.org/all/1652858.1769038134@warthog.procyon.org.uk/ [1]
Link: https://lore.kernel.org/all/1653031.1769038583@warthog.procyon.org.uk/ [2]
Link: https://lore.kernel.org/all/CANT5p=pXP3+CywpmK-on2uTvxO3S=31_B85_UDR7RoK1dQVtMA@mail.gmail.com/ [3]
Assisted-by: Codex:gpt-5.5
Assisted-by: Claude:claude-opus-5
Signed-off-by: Christopher Lusk <clusk@northecho.dev>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:07 -03:00
Christopher Lusk
deb6468f41 smb: client: fix request buffer leak in smb2_new_read_req()
smb2_new_read_req() allocates the request buffer with
smb2_plain_req_init() but only publishes it to the caller with
*buf = req at the very end of the function. Two error returns sit in
between:

	rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
				 (void **) &req, total_len);
	if (rc)
		return rc;

	if (server == NULL)
		return -ECONNABORTED;
	[...]
		rdata->mr = smbd_register_mr(server->smbd_conn,
					     &rdata->subreq.io_iter,
					     true, need_invalidate);
		if (!rdata->mr)
			return -EAGAIN;

On either of them the buffer is neither released nor handed back, so
it is leaked. The caller cannot clean up after it: smb2_async_readv()
does 'goto out' on a non-zero return, which skips the
cifs_small_buf_release(buf) at async_readv_out, and buf has not been
assigned at that point in any case.

The write path has never had this problem. smb2_async_writev()
registers the memory region inline and jumps to its release label
instead of returning:

	wdata->mr = smbd_register_mr(...);
	if (!wdata->mr) {
		rc = -EAGAIN;
		goto async_writev_out;
	}

Commit b797209219 ("cifs: smbd: Retry on memory registration
failure") changed both sides from -ENOBUFS to -EAGAIN in a single
patch, which puts the two shapes next to each other.

Only the -EAGAIN return is reachable in practice, because
smb2_plain_req_init() calls smb2_reconnect() first and that already
fails with -EIO when server is NULL, before anything is allocated.
Both returns are given the same treatment here rather than leaving
one of them correct only by accident.

Because -EAGAIN is a replayable error, the failure also reaches the
retry block at the end of smb2_async_readv(), which marks the
subrequest NETFS_SREQ_NEED_RETRY, so a failing registration can be
retried rather than ending the I/O, and every attempt that reaches it
leaks another buffer. smb2_should_replay() short-circuits on
tcon->retry, so on a hard mount the attempt count is not bounded by
the retrans setting.

Only the asynchronous read path is affected. The synchronous
SMB2_read() caller passes rdata == NULL and the memory registration
block is guarded on rdata.

The memory registration failure path was pointed out by the Sashiko
AI reviewer while it was reviewing an unrelated patch to
smb2_async_readv().

Fixes: bd3dcc6a22 ("CIFS: SMBD: Upper layer performs SMB read via RDMA write through memory registration")
Link: https://sashiko.dev/#/patchset/20260729192002.876156-1-clusk%40northecho.dev
Link: https://lore.kernel.org/all/20260729192002.876156-1-clusk@northecho.dev/
Assisted-by: Claude:claude-opus-5
Signed-off-by: Christopher Lusk <clusk@northecho.dev>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:30:00 -03:00
ChenXiaoSong
a2f9fb451c smb/client: return EOPNOTSUPP for unsupported O_TMPFILE
Some SMB servers return STATUS_OBJECT_NAME_NOT_FOUND or
STATUS_DELETE_PENDING when creating an O_TMPFILE.
The SMB client maps them to ENOENT.

The ENOENT error is supposed to be returned when the path
(a target directory in this case) does not exist, while a
lack of support of O_TMPFILE by the target file system should
be indicated by EOPNOTSUPP.

Reported-by: Mikhail Stefantsev <mikhail@mstefan99.com>
Fixes: 3e7d63037a ("smb: client: add support for O_TMPFILE")
Closes: https://lore.kernel.org/linux-cifs/75fb5359-b268-492d-8d4a-504d1af60f2a@app.fastmail.com/
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19 12:29:47 -03:00
Linus Torvalds
d47db9bf50 Crypto library updates for 7.3
Add library APIs for most AES encryption modes that are used in the
 kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).
 
 These AES modes have many in-kernel users that are currently using the
 crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
 to use and inefficient. Until now, the lack of proper library support
 for these has been the main gap in the crypto library.
 
 This set of changes is the next stage of addressing it:
 
   - Implement the new APIs on top of the existing support for
     single-block AES in the library.
 
   - Fully document the new APIs.
 
   - Migrate the only user of the old AES-GCM library API to the new,
     more flexible API; then remove the old API and its implementation.
 
   - Wire up the new APIs to the traditional crypto API by adding
     crypto_skcipher and crypto_aead algorithms.
 
     This makes the new APIs be covered by the traditional crypto API's
     self-tests. It also makes them be already used for real on systems
     that don't have architecture-optimized code for these modes.
 
     But most importantly, this is a prerequisite for migrating the
     architecture-optimized code for these AES modes (i.e.
     arch/*/crypto/aes*) into the library, which as usual will
     eliminate a lot of redundant "glue" code.
 
 Note that unlike some of the other algorithms that have been migrated
 to the library, e.g. SHA-512, for these AES modes there was too much
 to get done in one cycle. Nor did it make sense to handle these modes
 one at a time, because they tend to be coupled together or depend on
 each other, especially in the architecture-optimized AES code.
 
 Thus, most of the benefits (reductions in lines of code, performance
 improvements, etc.) will follow in later cycles when
 architecture-optimized code is migrated into the library and users of
 crypto_skcipher and crypto_aead are updated to use the new APIs.
 
 The design of the new APIs was informed by writing proof-of-concept
 patches for many kernel subsystems currently accessing these same
 algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
 https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).
 
 While those patches will be resent for real later, the total diffstat
 for them was negative 1905 lines. So clearly the new APIs are quite a
 bit easier to use and align better with what users actually need.
 
 Besides the new AES encryption APIs, there are also a few changes for
 improved AES-CMAC key and context zeroization.
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCaoEqhRQcZWJpZ2dlcnNA
 a2VybmVsLm9yZwAKCRDzXCl4vpKOKy8YAP4o44z09KdugtigFIFX7qQnLk0uPAw+
 sTPqmu+FA4jOGAD/Vy23hzAVpWmSBFhyo7HMK9W0ABK7cqj6x23I/N6JRgM=
 =SLPT
 -----END PGP SIGNATURE-----

Merge tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux

Pull crypto library updates from Eric Biggers:
 "Add library APIs for most AES encryption modes that are used in the
  kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).

  These AES modes have many in-kernel users that are currently using the
  crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
  to use and inefficient. Until now, the lack of proper library support
  for these has been the main gap in the crypto library.

  This set of changes is the next stage of addressing it:

   - Implement the new APIs on top of the existing support for
     single-block AES in the library.

   - Fully document the new APIs.

   - Migrate the only user of the old AES-GCM library API to the new,
     more flexible API; then remove the old API and its implementation.

   - Wire up the new APIs to the traditional crypto API by adding
     crypto_skcipher and crypto_aead algorithms.

     This makes the new APIs be covered by the traditional crypto API's
     self-tests. It also makes them be already used for real on systems
     that don't have architecture-optimized code for these modes.

     But most importantly, this is a prerequisite for migrating the
     architecture-optimized code for these AES modes (i.e.
     arch/*/crypto/aes*) into the library, which as usual will eliminate
     a lot of redundant "glue" code.

  Note that unlike some of the other algorithms that have been migrated
  to the library, e.g. SHA-512, for these AES modes there was too much
  to get done in one cycle. Nor did it make sense to handle these modes
  one at a time, because they tend to be coupled together or depend on
  each other, especially in the architecture-optimized AES code.

  Thus, most of the benefits (reductions in lines of code, performance
  improvements, etc.) will follow in later cycles when
  architecture-optimized code is migrated into the library and users of
  crypto_skcipher and crypto_aead are updated to use the new APIs.

  The design of the new APIs was informed by writing proof-of-concept
  patches for many kernel subsystems currently accessing these same
  algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
  https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).

  While those patches will be resent for real later, the total diffstat
  for them was negative 1905 lines. So clearly the new APIs are quite a
  bit easier to use and align better with what users actually need.

  Besides the new AES encryption APIs, there are also a few changes for
  improved AES-CMAC key and context zeroization"

* tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux:
  mac80211: fils_aead: Use __cleanup() instead of memzero_explicit()
  Bluetooth: SMP: clear the aes_cmac_key when done
  smb: clear the aes_cmac_key and aes_cmac_ctx when done
  lib/crypto: aes-cmac: Add zeroization functions
  lib/crypto: aesgcm: Remove old AES-GCM library
  x86/sev: Remove obsolete virtual address check
  x86/sev: Use new AES-GCM library
  crypto: aes - Add CCM support using library
  crypto: aes - Add GCM support using library
  crypto: aes - Add XTS support using library
  crypto: aes - Add CTR and XCTR support using library
  crypto: aes - Add CBC and CBC-CTS support using library
  crypto: aes - Add ECB support using library
  lib/crypto: aes: Add CCM support
  lib/crypto: aes: Add GCM support
  lib/crypto: aes: Add XTS support
  lib/crypto: aes: Add CTR and XCTR support
  lib/crypto: aes: Add CBC and CBC-CTS support
  lib/crypto: aes: Add ECB support
  crypto: xts - Split out __xts_verify_key() helper
2026-08-17 19:16:42 -07:00
Linus Torvalds
1c3e8cef79 vfs-7.3-rc1.misc
Please consider pulling these changes from the signed vfs-7.3-rc1.misc tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 otI6AQCIwshv02UI9fmbTC9pFr8b+v/9IWQwdVULaH61HXgICQD7BE/CktL8nfRs
 zCzGS6kBdWgiOA6bdVpgGGLqiMRnQgo=
 =Kc+G
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull misc vfs updates from Christian Brauner:
 "Bigger cleanups:

   - The lockref dead-count handling is tidied up.

     The open-coded check for a count below zero as the dead marker
     relies on information the caller should not have.

   - make put_mnt_ns() leave mounts connected. Destroying a mount
     namespace disconnected its mounts from their mount points. So a
     file descriptor still open on the parent of a mount point could be
     used to peek under it.

     Locked mounts were already kept connected to prevent exactly that.
     But a mount is only locked when its tree is copied across a user
     namespace boundary. So a mount namespace set up by a privileged
     component had no locked mounts and its mounts were disconnected.
     Passing UMOUNT_CONNECTED keeps every mount connected and prevents
     that bug.

   - vfs_prepare_mode() passes S_IFDIR for directories. I meant to fix
     that ago but didn't get to it. So now someone finally did it.

     This kills the exception where the mode could be 0 when a directory
     was created whereas every other creation operation passed it
     explicitly already.

   - move long delayed work for ufs, jffs2, hfsplus, hfs and affs from
     the per-cpu system_long_wq to the new unbound system_dfl_long_wq.

     None of that work relies on per-cpu state and the work item is
     enqueued with queue_delayed_work() whose timer is global anyway. So
     it may as well benefit from scheduler task placement.

  Smaller fixes and cleanups:

   - unlock_buffer() and journal_end_buffer_io_sync() use
     clear_and_wake_up_bit()

   - the pipe page pools are unified into a single per-pipe pool and the
     extra wake_up(rd_wait) is limited to EPOLLET consumers

   - eventpoll now computes its timer slack lazily in ep_poll()

   - shrink_dcache_for_umount() keeps making progress on busy roots

   - excess xarray nodes are freed in clear_inode()

   - romfs detects hard link cycles

   - the user path of nested backing files is fixed

   - pidfd holds exec_update_lock around the namespace ioctl

   - non-memcg-aware nr_cached_objects is skipped during memcg slab
     shrink

   - iomap_write_iter() always returns status

   - mangle_path() is renamed to seq_mangle_path()

   - inode timestamp accessors are annotated

   - new regression test for pipe->poll_usage.

   - a few documentation, kernel-doc and selftest fixes"

* tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (67 commits)
  selftests/namespaces: Fix racy pipe handshake in timens and pidns_separate
  selftests/epoll: add a regression test for pipe->poll_usage
  pipe: only enable the extra wake_up(rd_wait) for EPOLLET consumers
  pidfd: hold exec_update_lock around namespace ioctl
  fs: fix user path of nested backing files
  fs: remove stale inode_insert5() kernel-doc parameter
  fs: fix switch/case indentation in sysfs() syscall
  fs: document semantics of kstat::{uid,gid} fields
  dcache: keep shrink_dcache_for_umount() making progress on busy roots
  seq_file: rename mangle_path to seq_mangle_path
  nstree: add/fix struct ns_id_req kernel-doc member fields
  dcache: use lockref routines for dead count checks
  lockref: tidy up dead count handling
  initramfs: fix typo in reserve_initrd_mem comment
  fs/pipe: unify the page pools into a single per-pipe pool
  fs: annotate inode timestamp accessors
  eventpoll: compute timer slack lazily in ep_poll()
  selftests/filesystems: add mntns cleanup test
  put_mnt_ns(): leave mounts connected
  affs: Move long delayed work on system_dfl_long_wq
  ...
2026-08-17 12:56:12 -07:00
Linus Torvalds
ab5ed08f2d vfs-7.3-rc1.lookup
Please consider pulling these changes from the signed vfs-7.3-rc1.lookup tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 ouj6AQCnBHstCt5RRimywLYU+eTmdKe203zRQYxXpwlYOAzm7wEAm1mIC7/Of6bD
 jkiJilcPDcyYcJsqwBw/Vcz5HR+v8wo=
 =TX6K
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs lookup updates from Christian Brauner:
 "This refactors lookup_open() and adds vfs_lookup_open() for nfsd.

  mnt_want_write() and parent locking are moved into lookup_open()
  itself.

  audit_inode_child() is also now called in lookup_open() on failure.
  That is the calling convention in vfs_create() and vfs_mkdir(), but
  lookup_open() made no such call when atomic_open() should have created
  a file and did not. And neither did the regular ->create() path fwiw.

  This also contains work to remove the unneeded excl argument from the
  ->create() inode op"

* tag 'vfs-7.3-rc1.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  fs/namei.c: fix coding style in atomic_open() and lookup_open()
  fs/namei.c: fix kerneldoc of atomic_open() and vfs_lookup_open()
  fs/namei.c: update stale comments in lookup_open()
  Remove excl arg to ->create inode_operation
  fs/namei.c: update kerneldoc of atomic_open()
  vfs: call audit_inode_child() in lookup_open() on failure
  vfs: move create error && negative dentry case in lookup_open() up
  VFS: add vfs_lookup_open() for nfsd
  VFS: move delegated_inode retry loop into lookup_open()
  VFS: move mnt_want_write() and locking into lookup_open()
2026-08-17 12:03:34 -07:00
Linus Torvalds
fff0150b02 vfs-7.3-rc1.kthread
Please consider pulling these changes from the signed vfs-7.3-rc1.kthread tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 ohHuAQCFeGhxqsb44KhuJaWXewiXbefr6eg31lXmxgSfg0DILAD/Tw/WmpiUbX5M
 H+/jh6NmLKnQ/ADjlWFRy3R1K1Il3w4=
 =jwPP
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull kthread vfs updates from Christian Brauner:
 "This stops kernel threads from sharing filesystem state with
  userspace. This work is about 3 cycles old and has been in -next
  for about that time.

  When the kernel boots init_task creates PID 1 and then kthreadd. From
  that point every kthread and PID 1 share the same fs_struct. That is
  why pivot_root() has to rewrite the fs_struct of all kthreads. The
  rewriting exists so that kthreads can use init's filesystem state when
  they want to. It also means userspace can move the ground out from
  under the kernel.

  PID 1 now gets a completely separate fs_struct. All kthreads are
  anchored in a private SB_KERNMOUNT instance of nullfs that cannot be
  mounted on and cannot be used to follow other mounts. Userspace init
  can no longer affect kthread filesystem state and kthreads can no
  longer affect userspace fs state without explicit opting in to that.

  Path lookup from a kthread now fails by default. It makes it
  deliberately hard to offload security sensitive operations into init's
  filesystem state from a kthread.

  Places that legitimately need to look something up there opt in
  through the new scoped_with_init_fs() which temporarily overrides the
  caller's fs_struct with init's. usermodehelpers remain the only kernel
  tasks that genuinely share init's filesystem state, since they execute
  random binaries in the root filesystem (excellent...).

  The visible result is that /proc/2/root is a nullfs with an empty
  mountinfo while /proc/1/root is the real root"

* tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (26 commits)
  initramfs_test: use test init/exit hooks to override init fs
  fs: stop rewriting paths for PF_EXITING | PF_DUMPCORE
  fs: stop rewriting kthread fs structs
  fs: start all kthreads in nullfs
  nullfs: make nullfs multi-instance
  devtmpfs: create private mount namespace
  fs: add umh argument to struct kernel_clone_args
  fs: stop sharing fs_struct between init_task and pid 1
  af_unix: use scoped_with_init_fs() for coredump socket lookup
  initramfs: use scoped_with_init_fs() for rootfs unpacking
  pnfs/blocklayout: use scoped_with_init_fs() for SCSI device lookup
  ksmbd: use scoped_with_init_fs() for VFS path operations
  ksmbd: use scoped_with_init_fs() for filesystem info path lookup
  ksmbd: use scoped_with_init_fs() for share path resolution
  fs: use scoped_with_init_fs() for kernel_read_file_from_path_initns()
  coredump: use scoped_with_init_fs() for coredump path resolution
  btrfs: use scoped_with_init_fs() for update_dev_time()
  scsi: target: use scoped_with_init_fs() for APTPL metadata
  scsi: target: use scoped_with_init_fs() for ALUA metadata
  crypto: ccp: use scoped_with_init_fs() for SEV file access
  ...
2026-08-17 11:35:12 -07:00
Ze Tan
7de5cf9bcf smb/server: fix session counter on session removal
See the procedure below:

  smb2_sess_setup
    ksmbd_smb2_session_create
      __session_create
        hash_add(sessions_table, &sess->hlist, sess->id)
        ksmbd_counter_inc(KSMBD_COUNTER_SESSIONS)
  ksmbd_conn_handler_loop
    ksmbd_server_terminate_conn
      ksmbd_sessions_deregister
        hash_del(&sess->hlist)
        // do not decrement KSMBD_COUNTER_SESSIONS

KSMBD_COUNTER_SESSIONS tracks sessions published in sessions_table, but
session removal does not decrement it. The value therefore keeps growing
after sessions are expired, rejected during registration, or removed on
the last channel disconnect.

Fixes: b38f99c121 ("ksmbd: add procfs interface for runtime monitoring and statistics")
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:27 +09:00
Ze Tan
492b24b5b6 smb/server: update session counter under sessions table lock
KSMBD_COUNTER_SESSIONS tracks sessions published in sessions_table.
Increment it while holding sessions_table_lock so publishing a session and
updating the counter happen together.

Fixes: b38f99c121 ("ksmbd: add procfs interface for runtime monitoring and statistics")
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:26 +09:00
Ze Tan
99b25b046e smb/server: fix session leak in ksmbd_session_register()
See the procedure below:

  smb2_sess_setup
    ksmbd_smb2_session_create
      __session_create
        atomic_set(&sess->refcnt, 2)
        hash_add(sessions_table, &sess->hlist, sess->id)
    ksmbd_session_register
      xa_store(&conn->sessions, sess->id, sess) // fail
    ksmbd_user_session_put
      atomic_dec(&sess->refcnt) // refcnt is 1, session is not freed

Remove the session from sessions_table and drop its table reference if
xa_store() fails.

Fixes: f5c779b7dd ("ksmbd: fix racy issue from session setup and logoff")
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:26 +09:00
Ze Tan
9a74739026 smb/server: warn if ksmbd_proc_create() fails
Print a warning if the sessions procfs entry cannot be created.

Signed-off-by: Ze Tan <tanze@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:26 +09:00
Hang Nan
79decd88dd ksmbd: bound smb_check_perm_dacl() ACE walks by DACL size
smb_check_perm_dacl() validates that the DACL fits inside the NT
security descriptor, but then bounds its two ACE walks by the
remaining NTSD length (acl_size) rather than the DACL's declared
size (pdacl_size).

When pdacl->size is smaller than the trailing NTSD buffer, bytes
after the declared DACL boundary - still inside the stored security
descriptor - are parsed as ACEs during access checks.  A crafted
DACL can place an access-granting ACE beyond pdacl->size, and the
current code accepts it during SMB2_CREATE access validation, while
parse_dacl() and smb_inherit_dacl() stop at pdacl_size.

Bound both ACE walks by pdacl_size to match the DACL boundary
semantics used elsewhere in the server.

Validation:
- semantic KUnit harness shows the post-boundary ACE is selected
  before the fix and rejected (EACCES) after it
- linux master (7.2-rc6), x86_64

Fixes: 8f0541186e ("ksmbd: fix heap-based overflow in set_ntacl_dacl()")
Signed-off-by: Hang Nan <2122295973@qq.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:26 +09:00
Namjae Jeon
f7157d148d ksmbd: make RDMA encryption diagnostics conditional
The temporary RDMA encryption diagnostics logged every SMB3 request
and successful payload operation with pr_err(), which made normal
traffic too noisy.

Keep only negotiation, RDMA READ preparation, RDMA WRITE transform
metadata, crypto completion, and final transfer completion messages as
KSMBD_DEBUG_RDMA diagnostics. Keep error reports for malformed metadata,
crypto, RDMA transfer, and file write failures at error level.

This preserves the diagnostics needed to verify RDMA transform
operation without flooding the kernel error log during normal I/O.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-08-17 22:38:26 +09:00