summaryrefslogtreecommitdiff
path: root/fs/smb
AgeCommit message (Collapse)AuthorFilesLines
9 daystreewide: refresh kmalloc_obj() conversionsKees Cook5-5/+5
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org>
11 daysksmbd: fix tree connection use-after-free in smb2_tree_connect()Cen Zhang (Microsoft Security FORGE Labs)2-15/+21
ksmbd_tree_conn_connect() publishes a new tree connection in sess->tree_conns with a single reference and returns its pointer to smb2_tree_connect(). The handler continues to initialize the object and build the response after publication. A concurrent session logoff can erase the connection and drop that reference, freeing the object while the handler still uses it. BUG: KASAN: slab-use-after-free in smb2_tree_connect+0xe3d/0xf90 smb2_tree_connect (fs/smb/server/smb2pdu.c:2872) handle_ksmbd_work process_one_work worker_thread kthread After xa_store() succeeds, take a second reference before releasing tree_conns_lock. The original reference belongs to the xarray entry and the second belongs to the creating smb2_tree_connect() handler. Keep the references balanced in every path: - On normal exit or an error after publication, smb2_tree_connect() drops its creator reference. Error cleanup also calls ksmbd_tree_conn_disconnect(), which drops the xarray reference only if it removes the exact entry. - SMB2 TREE_DISCONNECT uses the same helper to remove the entry and drop its xarray reference. The request's existing lookup reference remains owned by the request and is released by the existing cleanup. - Session LOGOFF removes each entry and drops its xarray reference. If it wins the race, later cleanup sees that the entry is gone and does not drop that reference again. To enforce this ownership, claim the disconnected state and erase the exact entry atomically under tree_conns_lock. This guarantees one drop for the xarray reference and one drop by each in-flight user, regardless of which teardown path wins. If logoff removes the entry before initialization completes, fail the connect instead of marking the detached object TREE_CONNECTED. Fixes: 33b235a6e6eb ("ksmbd: fix race condition between tree conn lookup and disconnect") Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu> Cc: AutonomousCodeSecurity@microsoft.com Cc: stable@vger.kernel.org Signed-off-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
11 daysksmbd: validate COPYCHUNK source and target rangesAlon Shakevsky1-1/+11
ksmbd_vfs_copy_file_ranges() rejects negative source offsets in the copy loop, but it does not validate target offsets. It also calculates lock and overlap endpoints before ensuring that either range fits within MAX_LFS_FILESIZE. When the target is an alternate data stream, the buffered path passes a negative target offset to ksmbd_vfs_stream_write(). Let n be Length and let -d be TargetOffset, where 0 < d < n <= XATTR_SIZE_MAX. For an empty stream, the writer allocates n - d bytes, then copies n bytes starting d bytes before the allocation. An authenticated SMB client can control d and the source data, overwrite kernel heap memory, and crash the host. Validate both ranges before lock, overlap, or I/O calculations. Fixes: 8482150a0743 ("ksmbd: support copychunk for alternate data streams") Assisted-by: Antiproof:GPT-5.6-Sol Signed-off-by: Alon Shakevsky <shakevsky@berkeley.edu> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
11 daysksmbd: fix use-after-free in oplock break notificationAbdifatah Suruur1-16/+57
smb2_oplock_break_noti() reads opinfo->conn without any lock and dereferences it after two allocations which may sleep. When the durable handle owning the oplock is disconnected, session_fd_check() clears opinfo->conn and drops its conn reference under ci->m_lock, and the last ksmbd_conn_put() frees the connection. A break triggered by another connection that races with the teardown can then resurrect the freed connection: ksmbd_conn_get() is a plain atomic_inc, and the queued break work later dereferences the stale conn via ksmbd_conn_write(), a use-after-free reachable by any authenticated client holding a durable batch oplock. Thread the caller's inode into the notification path instead of taking a new reference on it. Every caller of oplock_break() already holds a live ksmbd_file (or an explicit ksmbd_inode_lookup_lock() reference, in the parent lease break paths) on the inode that owns the break target's oplock list, so ci cannot be freed during the call, and its lock can be taken without dereferencing opinfo->o_fp, which a concurrent close may free. Select and pin the connection under ci->m_lock, the same lock session_fd_check() and ksmbd_reopen_durable_fd() use to update opinfo->conn, so a concurrent detach either loses the race to the clear or keeps the connection alive until the notification work releases it. Transfer the reference to the work item and release it on allocation failures. Fixes: b003086d7696 ("ksmbd: fix NULL-deref of opinfo->conn in oplock/lease break notifiers") Cc: stable@vger.kernel.org Signed-off-by: Abdifatah Suruur <suruurism@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
11 daysksmbd: fix sparc build with atomic work stateNamjae Jeon1-1/+1
Use an unsigned int for the work state so xchg() uses a supported 4-byte operation on sparc. Fixes: d12168084c8c ("ksmbd: safely drain sessions during logoff") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202609021157.8f7Wx34I-lkp@intel.com/ Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
12 daysMerge tag 'cifs-fixes-7.3-rc2' of https://git.manguebit.org/linuxLinus Torvalds5-56/+231
Pull smb client fixes from Paulo Alcantara: - Fixes for fallocate range operations (insert, collapse, zero, punch hole) The insert range implementation copied overlapping chunks in the wrong direction, corrupting file data on every server except Windows. Several related issues in the same area are also addressed — stale page cache and FS-Cache readback, an integer truncation on large files, missing RLIMIT_FSIZE validation and missing sparse file marking. - Data corruption fixes in the O_TRUNC open path: one where i_size was zeroed before the server confirmed the truncate and another where the lack of locking allowed concurrent buffered writes to be silently discarded - Heap overflow fixes in legacy SMB1 paths: one in extended attribute writes and one in POSIX ACL handling, both exploitable via unprivileged setxattr(2) - Fix for multiuser mount with krb5 failing because the username option was not propagated to new per-user connections - Fix for split debug message in __release_mid() after a printk conversion * tag 'cifs-fixes-7.3-rc2' of https://git.manguebit.org/linux: smb: client: reject SetEA requests that do not fit the request buffer smb: client: fix data corruption with concurrent writes and O_TRUNC cifs: don't update i_size in cifs_do_truncate without a cached handle smb: client: fix heap overflow in cifs_do_set_acl() smb: client: fix multiuser mount with krb5 smb: client: transport: Fix debug printing in __release_mid() smb/client: invalidate fscache for fallocate range operations smb/client: fix stale page cache in insert/collapse range smb/client: fix integer truncation in collapse range smb/client: fix data corruption in emulated insert range smb/client: mark file sparse before emulating insert range smb/client: validate new EOF for zero range smb/client: validate new EOF for insert range cifs: add revalidation on FSCTL failure in smb2_duplicate_extents()
12 daysMerge tag 'ksmbd-for-7.3-rc2' of ↵Linus Torvalds10-68/+206
git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb Pull smb server fixes from Namjae Jeon: - Prevent unintended data exposure by clearing pipe compound padding and the response buffer - Initialize missing fields in FS_OBJECT_ID_INFORMATION, FS_CONTROL_INFORMATION, and FS_POSIX_INFORMATION - Propagate DACL parsing and allocation failures so malformed security descriptors are rejected - Rate-limit errors for unmapped SIDs to prevent kernel log flooding - Drain multichannel sessions during LOGOFF, wake deferred locks and cancellable requests, and ensure cancellation callbacks run only once - Fix listener kthread reference handling and teardown ordering during netdevice events - Validate normalized-name and IPC share configuration response lengths - Update the KSMBD MAINTAINERS entry and add Paulo Alcantara as an SMBDIRECT co-maintainer * tag 'ksmbd-for-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/smb: ksmbd: validate normalized name response length ksmbd: fix listener task lifetime on netdev events ksmbd: prevent out-of-bounds reads in share config responses ksmbd: rate limit unmapped SID errors ksmbd: propagate DACL parsing errors ksmbd: zero pipe read compound padding ksmbd: safely drain sessions during logoff MAINTAINERS: Update the KSMBD entry MAINTAINERS: Add Paulo Alcantara as an SMBDIRECT co-maintainer ksmbd: fill in FileSysIdentifier in FS_POSIX_INFORMATION ksmbd: initialize FileSystemControlFlags in FS_CONTROL_INFORMATION ksmbd: zero the FS_OBJECT_ID_INFORMATION buffer before filling it in
13 dayssmb: client: reject SetEA requests that do not fit the request bufferYunpeng Tian1-1/+10
CIFSSMBSetEA() copies the caller's extended attribute value into the SMB request buffer without checking that it fits. The requirement is stated in the source but was never implemented: /*BB add length check to see if it would fit in negotiated SMB buffer size BB */ /* if (ea_value_len > buffer_size - 512 (enough for header)) */ if (ea_value_len) memcpy(parm_data->list.name + name_len + 1, ea_value, ea_value_len); The only bound applied on the way in is in cifs_xattr_set(): #define MAX_EA_VALUE_SIZE CIFSMaxBufSize ... if (size > MAX_EA_VALUE_SIZE) CIFSMaxBufSize is the full payload capacity of the buffer, so a value of exactly that size leaves no room for the SMB header, the TRANS2 parameter block, the fealist header and the EA name that are written ahead of it in the same object. SendReceive() already enforces the correct limit on this very length: if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) but it is called after the copy has taken place. An unprivileged setxattr(2) on an SMB1 mount with a 250-byte name and a 16384-byte value writes 16384 bytes starting 345 bytes into a 16588-byte cifs_request object, ending 141 bytes past it: BUG: KASAN: slab-out-of-bounds in CIFSSMBSetEA+0xabc/0xde0 Write of size 16384 at addr ffff888003aa0159 by task init/68 __asan_memcpy+0x3c/0x60 CIFSSMBSetEA+0xabc/0xde0 cifs_xattr_set+0xd3a/0xff0 __vfs_setxattr+0x13e/0x1a0 The buggy address is located 345 bytes inside of allocated 16588-byte region Apply SendReceive()'s limit to the assembled request before the copy rather than after it, and widen the byte counters so the sum cannot wrap before it is tested. byte_count is also tested against U16_MAX, because it is stored in the 16-bit pSMB->ByteCount. That becomes reachable when CIFSMaxBufSize is raised at module load, where it may be set as high as 1024*127: with a 5-byte EA name and a 65521-byte value, count is exactly U16_MAX while byte_count is 65556, and cpu_to_le16() would truncate it to 20 and transmit a frame whose ByteCount does not match its length. Testing byte_count covers count as well, since byte_count is the larger of the two and count's only 16-bit consumer is written after this point. check_add_overflow() is evaluated first so that total_len is assigned before it is reported. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Yunpeng Tian <shionthanatos@gmail.com> Reported-by: Mingda Zhang <npczmd@qq.com> Reported-by: Gongming Wang <gmwgg05@gmail.com> Reported-by: Qinrun Dai <jupmouse@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Yunpeng Tian <shionthanatos@gmail.com> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
13 dayssmb: client: fix data corruption with concurrent writes and O_TRUNCPaulo Alcantara1-10/+18
cifs_do_truncate() flushes dirty pages with filemap_write_and_wait() and truncates the file on the server, but in the old code both operations ran without holding i_rwsem or invalidate_lock. A concurrent buffered write via netfs_perform_write() -- which only needs i_rwsem shared -- could dirty new pages after the flush but before the local truncation, and those pages would be silently discarded by cifs_setsize() -> truncate_pagecache(). Fix by acquiring inode_lock (exclusive i_rwsem) and filemap_invalidate_lock at the top of cifs_do_truncate(), so the entire flush-truncate-resize sequence is atomic with respect to: - buffered writes (blocked by exclusive i_rwsem, since netfs_start_io_write takes i_rwsem shared), - read page faults (blocked by exclusive invalidate_lock, since filemap_fault takes it shared), - writeback collection (blocked by netfs_wb_begin/netfs_wb_end around the server truncate and local resize, since netfs_writepages also acquires the wb lock). Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") Signed-off-by: Paulo Alcantara <pc@manguebit.org> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: stable@vger.kernel.org
13 daysksmbd: validate normalized name response lengthAlon Shakevsky1-2/+11
FILE_NORMALIZED_NAME_INFORMATION converts the open file path to UTF-16. smb2_allocate_rsp_buf() leaves these responses in the 448-byte small buffer, and get_file_normalized_name_info() converts the path without checking the remaining space. An authenticated client can query a long path and make smbConvertToUTF16() write beyond work->response_buf. Use the large response buffer for normalized-name queries. Before conversion, verify that the response has room for the worst-case UTF-16 output and its terminator. Fixes: 10aeff72ab82 ("ksmbd: support normalized name information") Assisted-by: Antiproof:GPT-5.6-Sol Signed-off-by: Alon Shakevsky <shakevsky@berkeley.edu> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: fix listener task lifetime on netdev eventsNamjae Jeon1-9/+27
The listener thread exits when its listening socket is shutdown. The netdevice notifier shuts down the socket before calling kthread_stop(), so the task_struct can be freed before kthread_stop() gets its reference. Create the listener in a stopped state and hold an extra task_struct reference until kthread_stop_put() completes. Also stop and release listeners before freeing their interface records during TCP teardown. Fixes: 3316a8fc840d ("ksmbd: server: avoid busy polling in accept loop") Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: prevent out-of-bounds reads in share config responsesNamjae Jeon2-19/+40
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length. Fixes: a677ebd8ca2f ("ksmbd: validate payload size in ipc response") Reported-by: Kanishka De Silva <kpskanna1915@gmail.com> Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: rate limit unmapped SID errorsNamjae Jeon1-2/+2
A client can include many structurally valid but unmapped SIDs in a DACL. Logging every mapping failure lets one request generate hundreds of kernel error messages. Rate limit the message to prevent an authenticated client from flooding the kernel log. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: Cheryl Babcock <cheryl@renat.io> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: propagate DACL parsing errorsNamjae Jeon1-25/+38
parse_dacl() silently accepts truncated ACEs and allocation failures, allowing set_info_sec() to continue with an incomplete ACL conversion. Return parsing and allocation errors to parse_sec_desc() so malformed security descriptors are rejected before inode attributes or ACL xattrs are updated. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: Cheryl Babcock <cheryl@renat.io> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: zero pipe read compound paddingNamjae Jeon1-1/+6
Compound response handling extends the last response iov to an eight-byte boundary. smb2_read_pipe() allocates only the payload size, so the alignment padding can expose up to seven bytes of uninitialized kernel heap memory. Allocate the aligned size and clear the unused tail before pinning the response buffer. Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound") Reported-by: Cheryl Babcock <cheryl@renat.io> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: safely drain sessions during logoffNamjae Jeon6-10/+77
SMB3 multichannel allows requests for one session to run on multiple connections. Wait for all channels bound to a session before freeing shared session objects. A deferred byte-range lock remains counted as a running request and only wakes when its file closes. Wake blocked locks during the drain without unpublishing or modifying their file objects. Synchronous CANCEL requests must invoke their cancellation callback to wake pending operations, while CHANGE_NOTIFY completion remains specific to the asynchronous path. Serialize session teardown with channel registration and previous-session cleanup, and use atomic work-state transitions so LOGOFF, CANCEL, and connection teardown invoke cancellation callbacks only once. Fixes: 76e98a158b20 ("ksmbd: fix race condition between destroy_previous_session() and smb2 operations()") Reported-by: Cheryl Babcock <cheryl@renat.io> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: fill in FileSysIdentifier in FS_POSIX_INFORMATIONAleksandr Khromov1-0/+3
smb2_get_info_filesystem() reports 56 bytes for FS_POSIX_INFORMATION, that is the whole of FILE_SYSTEM_POSIX_INFO, but never assigns FileSysIdentifier. Those eight bytes go to the client as they are found in the response buffer. The buffer is zeroed on allocation, so a standalone request leaks nothing. A compound request can leak: the offset of the next response is advanced by the length pinned for the previous one, so a reply that was written into the buffer and then dropped in favour of the short error response of smb2_set_err_rsp() stays there, and the next reply is laid over it with only the header cleared. Report the file system id statfs() returned, which is what the field is for. FileSysIdentifier is __le64 and f_fsid is a pair of ints, so assemble the value first, val[0] as the low half, and convert it on the way out. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Signed-off-by: Aleksandr Khromov <haa@amicon.ru> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: initialize FileSystemControlFlags in FS_CONTROL_INFORMATIONAleksandr Khromov1-0/+1
smb2_get_info_filesystem() reports 48 bytes for FS_CONTROL_INFORMATION, that is the whole of struct smb2_fs_control_info, but never assigns FileSystemControlFlags. Those four bytes go to the client as they are found in the response buffer. The buffer is zeroed on allocation, so a standalone request leaks nothing. A compound request can leak: the offset of the next response is advanced by the length pinned for the previous one, so a reply that was written into the buffer and then dropped in favour of the short error response of smb2_set_err_rsp() stays there, and the next reply is laid over it with only the header cleared. ksmbd does not implement quota tracking, so report no control flags. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Signed-off-by: Aleksandr Khromov <haa@amicon.ru> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
13 daysksmbd: zero the FS_OBJECT_ID_INFORMATION buffer before filling it inAleksandr Khromov1-0/+1
smb2_get_info_filesystem() reports 64 bytes for FS_OBJECT_ID_INFORMATION, that is the whole of struct object_id_info, but writes only 46 of them: - objid[] is 16 bytes, and when the volume UUID is not available only sizeof(stfs.f_fsid) (8) bytes are copied into it; - extended_info.version_string[] is STRING_LENGTH (28) bytes, and only strlen("1.1.0") (5) bytes are copied into it. The response buffer is zeroed on allocation (kvzalloc() in smb2_allocate_rsp_buf()), so for a standalone request the remaining 31 bytes are zero. In a compound request they need not be. The offset of the next response is advanced by the length pinned for the previous one, so if a preceding command wrote its reply into the buffer and then failed, smb2_set_err_rsp() pins only the short error response and the next reply lands inside the area that has already been written. Only the header is cleared there: memset((char *)rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); The client then receives up to 31 bytes of a response it was not meant to see, including one that failed with an access denied error. Clear the structure before filling it in. As a side effect version_string is now NUL terminated. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Suggested-by: ChenXiaoSong <chenxiaosong@chenxiaosong.com> Cc: stable@vger.kernel.org Signed-off-by: Aleksandr Khromov <haa@amicon.ru> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
14 dayscifs: don't update i_size in cifs_do_truncate without a cached handleFrank Sorenson1-4/+20
If find_writable_file() returns null, cifs_file_flush will return 0 without issuing set_file_size, and the outer 'if (!rc)' block will set i_size to 0 before telling the server to truncate. If the cifs_open() then fails, the inode will have size 0, while the server file is unchanged. Move the netfs_resize_file() and cifs_setsize() into the 'if (cfile)', so they only run after a successful set_file_size. In the no-handle else branch, evict stale pages with truncate_inode_pages before the O_TRUNC open to dispose of old cache pages, and let the open response set the i_size. Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") Cc: stable@vger.kernel.org Signed-off-by: Frank Sorenson <sorenson@redhat.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb: client: fix heap overflow in cifs_do_set_acl()Frank Sorenson1-2/+11
cifs_set_acl() validates ACL size using posix_acl_xattr_size(): 4 + (count * 8) // 4-byte header + 8 bytes per ACE cifs_do_set_acl() then calls posix_acl_to_cifs() to write the CIFS wire format into the same buffer: 6 + (count * 10) // 6-byte header + 10 bytes per ACE An ACL that passes the xattr-based check in cifs_set_acl() can overflow the heap when posix_acl_to_cifs() writes the larger CIFS format. Validate the CIFS format size against the remaining buffer space and USHRT_MAX before converting--data_count is __u16, so sizes above USHRT_MAX truncate the on-wire packet length, causing the server to apply a partial ACL. Replace MaxDataCount = 1000 with min(CIFSMaxBufSize, USHRT_MAX). Fixes: dc1af4c4b4721 ("cifs: implement set acl method") Cc: stable@vger.kernel.org Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb: client: fix multiuser mount with krb5Paulo Alcantara1-5/+16
Customer reported that they could no longer mount their SMB shares with multiuser mount option and krb5. Turned out that the client wasn't duplicating username option when creating multiuser connections, therefore failing to retrieve credentials as cifs.upcall(8) couldn't find them in keytab. Fix this by duplicating username option (if set) from original fs context before creating multiuser connections with krb5. Reproducer: ``` $ ktutil ktutil: add_entry -password -p testuser -k 1 -e aes256-cts Password for testuser@ZELDA.TEST: ktutil: write_kt /etc/krb5.keytab ktutil: quit $ klist -ke Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- ---------------------------------------------------------------- 1 testuser@ZELDA.TEST (aes256-cts-hmac-sha1-96) $ mount.cifs //w22-root2/scratch /mnt/1 -o \ uid=1000,sec=krb5,username=testuser@ZELDA.TEST,multiuser mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg) ``` Reported-by: Jacob Shivers <jshivers@redhat.com> Fixes: 12b4c5d98cd7 ("smb: client: fix krb5 mount with username option") Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: Namjae Jeon <linkinjeon@kernel.org> Cc: stable@vger.kernel.org Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb: client: transport: Fix debug printing in __release_mid()Andy Shevchenko1-6/+5
Long time ago during upgrading printk():s to the respective pr_<level>() calls one misconversion happened and nobody has noticed that. So, previously printk(KERN_DEBUG) + printk() worked as one long debug print since the trailing '\n' is only present in the followup printk() format string. The culprit change missed that and split the message to two on the different levels. Restore the original behaviour to make users be less confused in the most likely never happen cases of partially getting that message. Fixes: 0b456f04bcdf ("cifs: convert printk(LEVEL...) to pr_<level>") Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: invalidate fscache for fallocate range operationsHuiwen He1-0/+7
smb3_zero_range(), smb3_punch_hole(), smb3_insert_range(), and smb3_collapse_range() modify file contents through server-side range operations. These operations discard the affected page cache, but leave the FS-Cache cookie valid, so a later read may return data cached before the range operation. Fix this by invalidating FS-Cache after outstanding I/O has completed and before modifying the file on the server. Run the following as root on a CIFS mount with fsc enabled and an active CacheFiles backend: bash -c ' MNT=/mnt/cifs FILE="$MNT/repro" # Generate four 1 MiB random blocks: [A][B][C][D]. dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none # Expected contents after zeroing B: [A][zero][C][D]. cp /tmp/src /tmp/expected dd if=/dev/zero of=/tmp/expected bs=1M seek=1 count=1 \ conv=notrunc status=none cp /tmp/src "$FILE" # Populate FS-Cache, then discard the page cache. sync echo 1 > /proc/sys/vm/drop_caches cat "$FILE" > /dev/null sync echo 1 > /proc/sys/vm/drop_caches fallocate --zero-range -o 1M -l 1M "$FILE" if cmp -s /tmp/expected "$FILE"; then echo "readback: OK" else echo "readback: STALE DATA" fi ' Before this change, the readback differs from /tmp/expected: readback: STALE DATA After this change, it matches: readback: OK Fixes: 30175628bf7f ("[SMB3] Enable fallocate -z support for SMB3 mounts") Fixes: 31742c5a3317 ("enable fallocate punch hole ("fallocate -p") for SMB3") Fixes: 5476b5dd82c8 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE") Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Suggested-by: Namjae Jeon <linkinjeon@kernel.org> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: fix stale page cache in insert/collapse rangeHuiwen He1-5/+18
smb3_insert_range() and smb3_collapse_range() use truncate_pagecache_range() to invalidate the affected page cache. However, if off or old_eof is not page-aligned, the boundary pages are only partially zeroed and remain uptodate. As a result, the client may return stale data after a successful insert/collapse range operation. For example, with 4K pages: page 0 page 1 page 2 0------4K 4K------8K 8K------12K ^ ^ off=2K old_eof=10K Page 1 is removed from the page cache, while the boundary pages are only partially zeroed. After COPYCHUNK moves the data on the server, these cached pages may still return stale data. This can be reproduced on a CIFS mount: bash -c ' FILE=/mnt/scratch/repro # Use a 6 KiB file so EOF is not page-aligned. dd if=/dev/urandom of=/tmp/src bs=1K count=6 status=none # Expected: a 4 KiB hole followed by the original data. rm -f /tmp/expected truncate -s 4K /tmp/expected cat /tmp/src >> /tmp/expected cp /tmp/src "$FILE" # Prime the page cache before moving data on the server. cat "$FILE" > /dev/null fallocate --insert-range -o 0 -l 4K "$FILE" if cmp -s /tmp/expected "$FILE"; then echo "readback: OK" else echo "readback: STALE DATA" fi ' Fix this by writing back dirty data and discarding the page cache from the start of the page containing off to EOF before moving data on the server. Fixes: 9c8b7a293f50 ("smb3: fix temporary data corruption in insert range") Fixes: fa30a81f255a ("smb3: fix temporary data corruption in collapse range") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: fix integer truncation in collapse rangeHuiwen He1-2/+2
smb3_collapse_range() stores the ssize_t return value of smb2_copychunk_range() in an int. A successful copy larger than INT_MAX is truncated to a negative value and treated as an error. Reproducer: MNT=/mnt/scratch truncate -s 2056M "$MNT/file" fallocate --collapse-range -o 1M -l 1M "$MNT/file" Fix this by using __smb2_copychunk_range(), which reports success as zero instead of returning the copied byte count. Before this change, the reproducer fails with: fallocate: fallocate failed: Success and the file size remains unchanged at 2056 MiB. After this change, the reproducer succeeds and the file size becomes the expected 2055 MiB. Fixes: 5476b5dd82c8 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: fix data corruption in emulated insert rangeHuiwen He1-26/+106
smb3_insert_range() shifts [off, EOF) right with COPYCHUNK, copying from low to high offsets. When the ranges overlap, the copy can overwrite source data that has not yet been copied. For a 1 MiB insert at offset 0: offset: 0 1M 2M 3M 4M 5M before: | A | B | C | D | expected: | hole | A | B | C | D | current: | hole | A | A | A | A | (corrupted) Let x be the insertion offset, L the total length to move, delta the insert length, and C the normal chunk size allowed by the server. Insert range maps [x, x + L) -> [x + delta, x + delta + L). When delta >= L, the complete source and target ranges are disjoint, so the normal copy order and chunk size are safe: offset: 0 4 8 12 16 20 24 28 32 source: [--S0--][--S1--][--S2--][--S3--] target: [--T0--][--T1--][--T2--][--T3--] When delta < L, the complete source and target ranges overlap, so the copy must proceed from EOF backwards. There are two subcases. If delta >= C, each corresponding source and target chunk is disjoint. The 1 MiB example has L = 4 MiB and delta = C = 1 MiB: offset: 0 1M 2M 3M 4M 5M source: [--S0--][--S1--][--S2--][--S3--] target: [--T0--][--T1--][--T2--][--T3--] Copying S0 from [0, 1M) to [1M, 2M) overwrites S1 before it is copied. Processing chunks from EOF backwards prevents this inter-chunk overwrite. If delta < C, the source and target ranges of a normal chunk also overlap. For example, with L = 16, delta = 2 and C = 4: offset: 0 2 4 6 8 10 12 14 16 18 source: [--S0--][--S1--][--S2--][--S3--] target: [--T0--][--T1--][--T2--][--T3--] Here S0 and T0 overlap over [2,4), S1 and T1 over [6,8), and so on. Backward ordering cannot control how the server copies bytes inside one descriptor, so the chunk size must be limited to delta. Fix this by copying overlapping right shifts from EOF backwards. Limit the chunk size to delta when delta < C so that each chunk's source and target ranges do not overlap. Using larger chunks would require a way to identify servers that safely handle overlapping COPYCHUNK descriptors. Therefore: delta >= L: keep the normal copy order and chunk size delta < L: delta >= C: copy backwards and keep the normal chunk size delta < C: copy backwards and limit the chunk size to delta Only the delta < C subcase requires reducing the chunk size for data integrity. Reproducer: bash -c ' MNT=/mnt/scratch # Generate four 1 MiB random blocks: [A][B][C][D]. dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none # With C = 1 MiB, test delta = C and delta < C. for delta in 1M 1K; do truncate -s 0 /tmp/expected truncate -s "$delta" /tmp/expected cat /tmp/src >> /tmp/expected cp /tmp/src "$MNT/file" fallocate --insert-range -o 0 -l "$delta" "$MNT/file" if cmp -s /tmp/expected "$MNT/file"; then echo "delta=$delta: OK" else echo "delta=$delta: CORRUPTED" fi done ' The corruption reproduces with Samba and ksmbd, while Windows handles the overlapping COPYCHUNK ranges safely. The 1 MiB case tests delta >= C, while the 1 KiB case tests delta < C. Before this change, the reproducer reports: delta=1M: CORRUPTED delta=1K: CORRUPTED After this change, it passes against both ksmbd and Samba: delta=1M: OK delta=1K: OK Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: mark file sparse before emulating insert rangeHuiwen He1-0/+5
The SMB client emulates FALLOC_FL_INSERT_RANGE with SET_EOF, COPYCHUNK and SET_ZERO_DATA. SET_ZERO_DATA creates a hole only when the file is sparse. On a non-sparse file, it clears the inserted range but leaves its blocks allocated, causing the extent count check in xfstests generic/064 to fail. Fix this by marking the file sparse before modifying it. This patch produces the expected sparse extents in xfstests generic/064 only when the server-reported block size is compatible with the server's deallocation granularity. For ksmbd, the reported block size follows the backing filesystem, and the test passes. For Samba, the test passes with a block size matching the backend granularity, for example, 4 KiB on Btrfs, but not with the default 1 KiB value. For Windows Server 2022, 4 KiB inserts do not generate holes, while aligned inserts of 64 KiB or larger do. Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: validate new EOF for zero rangeHuiwen He1-1/+8
When FALLOC_FL_ZERO_RANGE is used without FALLOC_FL_KEEP_SIZE, smb3_zero_range() may extend EOF without checking RLIMIT_FSIZE, allowing the file to grow beyond the caller's file-size limit. Fix this by calling inode_newsize_ok() before sending the zero-range request when the operation would extend EOF. Reproducer, using a file on a CIFS mount: bash -c ' FILE=/mnt/cifs/repro trap "" SIGXFSZ ulimit -f 3072 truncate -s 2M "$FILE" fallocate --zero-range -o 0 -l 4M "$FILE" echo "fallocate rc=$?" stat -c "file size=%s" "$FILE" ' Before this change, the operation succeeds despite the 3 MiB limit: fallocate rc=0 file size=4194304 After this change, fallocate fails and leaves the file at 2 MiB. Fixes: 72c419d9b073 ("cifs: fix smb3_zero_range so it can expand the file-size when required") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
14 dayssmb/client: validate new EOF for insert rangeHuiwen He1-2/+10
smb3_insert_range() does not check if the new file size (i_size + len) is valid. This allows FALLOC_FL_INSERT_RANGE to bypass RLIMIT_FSIZE, exceed s_maxbytes, or produce a size outside the loff_t range. Use check_add_overflow() to calculate the new EOF. Validate it with inode_newsize_ok() before modifying the file. Reproducer, using a file on a CIFS mount: bash -c ' FILE=/mnt/cifs/repro trap "" SIGXFSZ ulimit -f 3072 # RLIMIT_FSIZE = 3 MiB # A regular write is stopped at 3 MiB. dd if=/dev/zero of="$FILE" bs=1M count=4 status=none stat -c "size after write: %s" "$FILE" # Insert 2 MiB into a 2 MiB file. truncate -s 2M "$FILE" fallocate -i -o 0 -l 2M "$FILE" stat -c "size after insert: %s" "$FILE" ' Before this change, the regular write stops at the 3 MiB limit, but insert range grows the file to 4 MiB: dd: error writing '/mnt/cifs/repro': File too large size after write: 3145728 size after insert: 4194304 After this change, insert range also fails at the limit and leaves the 2 MiB file unchanged: dd: error writing '/mnt/cifs/repro': File too large size after write: 3145728 fallocate: fallocate failed: File too large size after insert: 2097152 Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support") Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-27Merge tag 'mm-stable-2026-08-26-15-22' of ↵Linus Torvalds1-26/+39
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull more MM updates from Andrew Morton: - "mm/rmap: index MAP_PRIVATE file-backed folios by anonymous pgoff" (Lorenzo Stoakes) Index MAP_PRIVATE file-backed folios by their anonymous page offset to resolve confusion around reverse mapping for zeroed and CoW'd file-backed memory. Use this new VMA anonymous page offset tracking to eliminate index conflicts and lay the foundation for scalable CoW performance improvements. - "promote mapped executable folios after first usage for MGLRU" (Baolin Wang) Make MGLRU's protection of mapped executable file folios more reliable. Follow the classical LRU's logic, promoting mapped executable file folios after their first usage to give executable code a better chance to stay in memory and improve workload performance. - "mm: vmscan: fix node reclaim ignoring swappiness parameter" (Ridong Chen) Fix per-node proactive reclaim interface's ignoring the swappiness parameter when CONFIG_MEMCG is disabled by consolidating sc_swappiness() into a single function that checks proactive_swappiness regardless of kernel configuration. - "mm/vmscan: reduce lru_lock contention via vmstat-derived scan-balance cost" (Usama Arif) Reduce lru_lock contention in the reclaim path by deriving scan-balance costs from vmstat counters rather than lock-acquired producer updates. Read and decay these cost signals on the reclaim side under a dedicated per-lruvec lock, reducing total LRU lock wait time by over 60% without impacting scan throughput. - "zram: fix zram issues reported by sashiko" (Sergey Senozhatsky) Fix two low-risk zram bugs which Sashiko spotted in drive-by review. - "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg" (Zi Yan) Fix xas_split_alloc() by enabling target folio memcg charging during splits and adding the missing __GFP_ACCOUNT flag for proper XArray node memory accounting. - "selftests/mm: use pattern matching in .gitignore" (Pratyush Mallick) Replace hardcoded binary names in selftests/mm/.gitignore with a generic pattern-matching rule to automatically ignore generated test files and avoid manual updates when adding new tests. - "mm/page_ext: remove pgdat_page_ext_init()" (Sang-Heon Jeon) Make the incompatibility between FLATMEM and NUMA explicit in mm/Kconfig and remove the unused pgdat_page_ext_init() function. - "zram: fix zstd error paths and add parameter validation" (Haoqin Huang) Clean up zram compression backends by removing redundant error cleanup, adding parameter and dictionary validation, auto-prefixing algorithm error logs, and resetting parameters prior to reinitialization. - "zram: fix stale scan bounds after reinitialization" (Longlong Xia) Prevent out-of-bounds slot accesses during concurrent zram resets by moving table scan bound calculations under dev_lock in writeback_store() and read_block_state(). - "add anon mTHP collapse test cases" (Baolin Wang) Extend selftests helper functions to support arbitrary page orders and add new test cases and options for mTHP collapse in khugepaged. - "selftests/mm: Handle unsupported and transient test conditions" (Muhammad Usama Anjum) Update MM selftests to report a SKIP status instead of a failure when required kernel or filesystem features are unsupported, while adding retry logic for transient page migration errors. - "mm/zswap: Fixes and improves the zswap shrink" (Hao Jia) Fix the missing zswap global shrinker when CONFIG_MEMCG is disabled and extend shrink_memcg() to support batch writeback for improved writeback efficiency. - "alloc_tag: introduce IOCTL-based filtering for MAP" (Suren Baghdasaryan) Introduce an IOCTL-based binary interface for memory allocation profiling that enables kernel-side filtering before per-CPU counter aggregation. This eliminates the text-parsing overhead of /proc/allocinfo and provides up to a 20x speedup by transferring only filtered allocation data to userspace. - "better block swap batching and a different take on swap_ops v5" (Christoph Hellwig) Refactor block swap I/O to use swap_iocb for batching instead of single-bio requests and rebase the swap_ops interface, achieving faster swap throughput during kernel builds. - "mm: kmemleak: reduce transient false positives by confirming leaks" (Catalin Marinas) Reduce false-positive kmemleak reports by combining two kmemleak enhancements that add a second confirmation scan and a configurable minimum unreferenced scan count module parameter. - "mm: kmemleak: default min_unref_scans to 2 for verbose kernels" (Breno Leitao) Auto-scanning kernels can generate false-positive memory leak reports on single scans, so this patch defaults min_unref_scans to 2 when CONFIG_DEBUG_KMEMLEAK_VERBOSE is enabled to require a second confirming scan. - "swap_ops updates" (Christoph Hellwig) Batching I/O for synchronous swap devices causes performance regressions and filesystem-based swap suffers from double-indirection overhead. This series resolves both issues by reintroducing per-folio writes for synchronous swap and allowing filesystems to directly export their own swap_ops. - "mm/khugepaged: several cleanups" (Nico Pache) khugepaged accumulated redundant state-checking patterns and outdated comments following mTHP integration. Introduce dedicated helpers for PTE validation and event counting while refreshing the internal documentation. - "maple_tree: lock checking and clean ups" (Liam Howlett) Syzbot reports incorrectly blame memory management exit paths for locking bugs, maple tree erase operations risk allocation failures without gfp flags and internal documentation lacks clarity. Improve lock error detection, update docs, fix race and allocation edge cases and optimize erase allocations using a fallback to GFP_KERNEL | GFP_NOFAIL. * tag 'mm-stable-2026-08-26-15-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (172 commits) selftests/proc: make proc-maps-race work with READ_IMPLIES_EXEC memcg: move LRU size accounting on reparenting instead of copying it mm/vmscan: fix comment logic in balance_pgdat maple_tree: add helper mas_make_walkable() maple_tree: avoid extra gap calculation maple_tree: fix argument name in header maple_tree: change two GFP flags in tests maple_tree: document erase and allocations better maple_tree: avoid mas_erase() and mtree_erase() failures maple_tree: document that erase may use GFP_KERNEL for allocations maple_tree: catch race in mas_alloc_cyclic() maple_tree: add bulk parent set helper maple_tree: micro optimisation of mas_wr_store_type() maple_tree: optimise mas_wr_node_store() when not in rcu mode maple_tree: use prefetched value in mas_wr_store_type() maple_tree: clarify comments on mas_nomem() maple_tree: drop MAPLE_ALLOC_SLOTS maple_tree: drop dead code from mas_extend_spanning_null() maple_tree: documentation fix maple_tree: add write lock checking with lockdep sequence numbers ...
2026-08-26cifs: add revalidation on FSCTL failure in smb2_duplicate_extents()Frank Sorenson1-2/+5
smb2_duplicate_extents() has no handling for FSCTL_DUPLICATE_EXTENTS_TO_FILE failure: when the FSCTL fails, local inode metadata may be stale from the pre-extension or from concurrent remote writes, but is never refreshed. Force revalidation on FSCTL failure and use i_size_read() for the pre-extension check. Fixes: cfc63fc8126a ("smb3: fix cached file size problems in duplicate extents (reflink)") Cc: stable@vger.kernel.org Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24mm/swap: move swap_ops into file systems for file system-based swapChristoph Hellwig1-24/+39
Currently swap to and from file systems goes through two indirect calls between the swap ops and the swap_rw method. Reduce this by directly providing the swap_ops from the file system. For this refactor swap_fs_submit into a swap_fs_prepare_rw helper that initializes the iov_iter on the callers stack so that file systems can call it directly, and use that to initialize file system specific ops in the NFS and SMB clients, which then get passed to swap_fs_activate. Link: https://lore.kernel.org/20260723054622.3460249-4-hch@lst.de Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Chris Li <chrisl@kernel.org> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Kairui Song <kasong@tencent.com> Cc: Kairui Song <ryncsn@gmail.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Steve French <sfrench@samba.org> Cc: Usama Arif <usama.arif@linux.dev> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-08-24mm/swap: remove SWP_FS_OPSChristoph Hellwig1-3/+1
Provide a swap_fs_activate helper that directly sets up swap_fs_ops, and a flag in struct swap_ops to indicate of NOFS swapping is allowed. Link: https://lore.kernel.org/20260713093350.2154226-7-hch@lst.de Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Youngjun Park <youngjun.park@lge.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-08-24Merge tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linuxLinus Torvalds22-108/+223
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-24cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0Frank Sorenson1-2/+13
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: 04b38d601239 ("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-24smb: client: reject a tree connect response whose byte count is too smallBryam Vargas2-1/+8
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: cc20c031bb06 ("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-24cifs: call pagecache_isize_extended() in cifs_setsize() when extendingFrank Sorenson1-0/+2
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-24smb: client: fix copy-paste error in WSL EA length accounting for $LXDEVFrank Sorenson1-1/+1
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: 97db41604555 ("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-24smb: client: remove redundant NULL check before kfree()Mohammad Shahid1-2/+1
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-24smb: client: restore the data_offset bound in is_valid_oplock_break()Bryam Vargas1-1/+2
Commit 83bfbd0bb902 ("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 097f5863b1a0 ("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: 83bfbd0bb902 ("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-24cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()Frank Sorenson1-0/+1
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: 110fee6b9bb5 ("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-24smb: client: Avoid leaking sensitive data to the heap in connect.cThomas Huth1-1/+1
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-24smb: client: Clear sensitive stack data in smb1encrypt.cThomas Huth1-10/+9
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-24smb: client: Clear sensitive stack data in cifsencrypt.cThomas Huth1-3/+9
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-24smb: client: Clear sensitive stack and heap data in smb2ops.cThomas Huth1-2/+2
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-24smb: client: Clear sensitive stack data in smb2transport.cThomas Huth1-0/+4
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-24Revert "cifs: remove all cifs files before kill super"Zizhi Wo1-3/+0
This reverts commit 6d9a4aaaa8b2612b5ef9d581e2f286a458b71ee1. 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 75f5c412fa86 ("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 6d9a4aaaa8b2 ("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-24smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()Frank Sorenson1-2/+4
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: a158bb66b137 ("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-24smb: client: fix ALIGN() overflow in symlink_data() error context loopFrank Sorenson1-1/+4
The check added by commit 7d9a7f1f96cd ("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: 76894f3e2f71 ("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>