summaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
2026-07-19gfs2: Remove the glock lru list and shrinkerAndreas Gruenbacher7-201/+15
We are no longer keeping unreferences glocks around, so remove the now-obsolete glock lru list and shrinker. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2026-07-19gfs2: Skip dlm unlocks earlierAndreas Gruenbacher5-7/+2
When we were still caching unreferenced glocks, evicting all the cached inodes in gfs2_kill_sb() did put the unreferenced glocks onto the glock lru list, and they would be freed in gfs2_gl_hash_clear(). We could set the SDF_SKIP_DLM_UNLOCK flag in gfs2_gl_hash_clear() to indicate to gdlm_put_lock() to skip unlocking glocks explicitly when possible. Now, glocks are demoted and dropped immediately though, so to allow gdlm_put_lock() to skip unnecessary unlocking, we need to set some "unmount" flag before calling gfs2_evict_inodes(). We can use the existing SDF_KILL flag for that if we set it before calling gfs2_evict_inodes() in gfs2_kill_sb(). Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2026-07-19gfs2: Don't cache unreferenced glocksAndreas Gruenbacher1-8/+13
Currently, gfs2 caches unreferenced glocks until memory pressure sets in or the filesystem is unmounted. This was supposedly done to avoid excessive log flushing: when a glock still has outstanding revokes, freeing it requires an extra log flush, and we want to avoid too many of those extra log flushes. Since commit 9287c6452d2b1 ("gfs2: Fix occasional glock use-after-free"), outstanding revokes are accounted for in the glock reference count and glocks with outstanding revokes will never be freed anymore, so this is no longer an issue. This also means that we won't need a glock LRU list anymore, but we leave removing that list to a later patch for better readability. It might seem that glocks that are not referenced anymore can be dropped immediately without unlocking them first, but that isn't true for inode glocks that have an address space attached (the "gfs2_glock(aspace)" slab cache): that address space is only truncated when the associated glock is unlocked. So unlock those glocks when they become unreferenced. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2026-07-19gfs2: Enable automatic glock hash table shrinkingAndreas Gruenbacher1-0/+1
All of the examiner functions passed to glock_hash_walk() can deal with glock hash table resizes and the resulting repeat visiting of glocks, so we can allow automatic glock hash table shrinking. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2026-07-18debugfs: warn if file creation failed due to uninitialized debugfsYohei Kojima1-1/+4
Improve debugfs_start_creating() to warn if it was used before debugfs initialization. It silently returned ERR_PTR(-ENOENT) before, but it is hard to find the cause of failure especially if it was called by debugfs_create_dir(), because the document of the function says: > NOTE: it's expected that most callers should _ignore_ the errors returned > by this function. Other debugfs functions handle the fact that the "dentry" > passed to them could be an error and they don't crash in that case. > Drivers should generally work fine even if debugfs fails to init anyway. Signed-off-by: Yohei Kojima <yk@y-koj.net> Link: https://patch.msgid.link/6d1dc775f7d5e754d734907514534054f682bac5.1781171918.git.yk@y-koj.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18kernfs: Replace strcpy(s, "../") with memcpy(s, "../", 4)David Laight1-1/+1
The code has already checked there is enough room. Use memcpy() to avoid compiler warnings from possibly unbounded strcpy(). Signed-off-by: David Laight <david.laight.linux@gmail.com> Link: https://patch.msgid.link/20260606202633.5018-6-david.laight.linux@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18kernfs: simplify kernfs_name_hash()Dmitry Antipov1-2/+2
In 'kernfs_name_hash()', 'name' is NUL-terminated so it may be directly scanned up to end without an extra call to 'strlen()'. Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> Link: https://patch.msgid.link/20260617073941.472337-1-dmantipov@yandex.ru Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-17Merge tag 'v7.2-rc3-smb3-server-fixes' of git://git.samba.org/ksmbdLinus Torvalds5-32/+56
Pull smb server fixes from Steve French: "ksmbd server fixes, mostly addressing malformed SMB request handling and connection/session lifetime issues, including two information-disclosure or memory-safety bugs in the SMB2 request/response paths. - validate FILE_ALLOCATION_INFORMATION before block rounding to prevent a client-controlled overflow from truncating a file. - pin connections while asynchronous oplock and lease-break notifications are pending. - initialize compound SMB2 READ alignment padding, preventing disclosure of uninitialized heap bytes. - release the allocated alternate-stream xattr name after rename. - size multichannel binding session-key buffers for the largest permitted key, avoiding a stack buffer overflow. - remove a disconnecting connection's channels from every session, including channels whose binding state has since changed. - serialize binding preauthentication-session lookup and update against its teardown. - check that every compound request element contains StructureSize2 before reading it" * tag 'v7.2-rc3-smb3-server-fixes' of git://git.samba.org/ksmbd: ksmbd: validate compound request size before reading StructureSize2 ksmbd: lock the binding preauth session in smb3_preauth_hash_rsp ksmbd: remove stale channels from all sessions on teardown ksmbd: fix stack buffer overflow in multichannel session-key copy ksmbd: fix memory leak of xattr_stream_name in smb2_rename() ksmbd: zero the smb2_read alignment tail to avoid an infoleak ksmbd: pin conn during async oplock break notification ksmbd: fix integer overflow in set_file_allocation_info()
2026-07-18ntfs: preserve RECALL_ON_OPEN on WSL special-file reparse pointsNamjae Jeon1-1/+2
When creating a WSL special file (socket, fifo, character or block device), __ntfs_create() sets FILE_ATTRIBUTE_RECALL_ON_OPEN in ni->flags as valid_reparse_data() requires for these tags. This flag is intentionally absent from $FILE_NAME, so the subsequent reload ni->flags = fn->file_attributes; drops it from ni->flags, the authoritative copy written back to $STANDARD_INFORMATION. The on-disk file_attributes becomes 0x00000404 instead of 0x00040404, and after a remount valid_reparse_data() rejects the reparse point while fsck reports "$REPARSE_POINT data is corrupted". Preserve the RECALL_ON_OPEN bit across the reload. Symlinks do not set that bit, so they are unaffected. Fixes: af0db57d4293 ("ntfs: update inode operations") Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-07-17ecryptfs: hold msg ctx list lock when cleaning daemon queueYichong Chen1-0/+2
ecryptfs_exorcise_daemon() drops queued messages from a dying daemon without holding ecryptfs_msg_ctx_lists_mux, but ecryptfs_msg_ctx_alloc_to_free() requires that lock. Take the list lock while moving the queued contexts back to the free list to avoid racing with other global msg ctx list users. Fixes: f66e883eb618 ("eCryptfs: integrate eCryptfs device handle into the module.") Cc: <stable@vger.kernel.org> Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: Tyler Hicks <code@tyhicks.com>
2026-07-17ecryptfs: release message context on send failureYichong Chen1-1/+8
ecryptfs_send_message_locked() moves a message context from the free list to the allocated list before sending the request to the userspace daemon. If ecryptfs_send_miscdev() fails, the context is left on the allocated list and cannot be reused. Move it back to the free list on failure and clear the caller's pointer. Fixes: f66e883eb618 ("eCryptfs: integrate eCryptfs device handle into the module.") Cc: <stable@vger.kernel.org> Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: Tyler Hicks <code@tyhicks.com>
2026-07-17ecryptfs: reject oversized encrypted_key_size in parse_tag_3_packetHanQuan1-2/+12
parse_tag_3_packet() set encrypted_key_size from the Tag 3 packet body without bounding it against ECRYPTFS_MAX_KEY_BYTES (64). When encrypted_key_size > 64, decrypt_passphrase_encrypted_session_key() sets decrypted_key_size = encrypted_key_size and performs two out-of-bounds writes: 1. crypto_skcipher_decrypt() writes encrypted_key_size bytes into decrypted_key[64] via scatterlist, overflowing into the parent ecryptfs_auth_tok struct. 2. memcpy(crypt_stat->key, decrypted_key, decrypted_key_size) writes into crypt_stat->key[64], corrupting root_iv, keysig_list, and mutexes in ecryptfs_crypt_stat. Only AES-192 (cipher code 0x08) enables this because it sets crypt_stat->key_size = 24 independently of encrypted_key_size, allowing crypto_skcipher_setkey() to succeed while encrypted_key_size exceeds ECRYPTFS_MAX_KEY_BYTES. The PKI decryption path (parse_tag_65_packet) already validates decrypted_key_size <= ECRYPTFS_MAX_KEY_BYTES; the passphrase path omits this check. Bound encrypted_key_size against ECRYPTFS_MAX_KEY_BYTES (64) rather than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES (512). The 64-byte limit also protects the 512-byte encrypted_key[] buffer, so the former 512-byte check is removed as redundant. Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig") Cc: <stable@vger.kernel.org> Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com> [tyhicks: Adjust the code comment to refer to macros representing the buffer sizes rather than mentioning the buffer size values since they may change in the future] Signed-off-by: Tyler Hicks <code@tyhicks.com>
2026-07-17lockd: fix NLMv3 GRANTED_MSG handlingOlga Kornievskaia1-1/+2
GRANTED_MSG is a server-to-client callback, so it runs on the client, where nfsd never registers nlmsvc_ops. The nlm3svc_lookup_host() helper is for the server-side request handlers (TEST/LOCK/CANCEL/UNLOCK), which reach nlmsvc_ops->fopen and must reject requests when nfsd isn't running. GRANTED_MSG only calls nlmclnt_grant(). Instead, of calling nlm3svc_lookup_host(), which results in a client failing a GRANTED_MSG call, call nlmsvc_lookup_host(). Fixes: 6c534ad999b6 ("lockd: Use xdrgen XDR functions for the NLMv3 GRANTED_MSG procedure") Cc: stable@vger.kernel.org Signed-off-by: Olga Kornievskaia <okorniev@redhat.com> Reviewed-by: NeilBrown <neil@brown.name> Link: https://patch.msgid.link/20260625211852.31972-1-okorniev@redhat.com Signed-off-by: Chuck Lever <cel@kernel.org>
2026-07-17fuse: allow larger read requests by setting bdi->io_pagesJim Harris1-0/+1
A FUSE server that advertises a large max_pages and max_write (e.g. max_pages=256, max_write=1MB) cannot currently obtain matching FUSE_READ request sizes from the kernel. Buffered sequential writes arrive at the server at the negotiated max_write size, but a large buffered read() is split into several smaller FUSE_READ requests. For a buffered read, filemap_get_pages() -> page_cache_sync_ra() sizes the read against ractl_max_pages(): max_pages = ractl->ra->ra_pages; if (req_size > max_pages && bdi->io_pages > max_pages) max_pages = min(req_size, bdi->io_pages); fuse leaves bdi->io_pages at the default VM_READAHEAD_PAGES (128KB), so a 1MB read() (req_size = 256 pages) is clamped to the readahead window (128KB, or 256KB for POSIX_FADV_SEQUENTIAL), producing four 256KB FUSE_READ round-trips instead of one. Set bdi->io_pages to fc->max_pages after feature negotiation. As the code above shows, io_pages only raises the limit when the request size already exceeds the readahead window, so it enlarges explicitly requested reads without enlarging the speculative readahead window. This avoids increasing speculative page-cache readahead on behalf of an unprivileged server. NFS does the same, setting io_pages from rpages while leaving ra_pages at the default. fc->max_pages is already bounded by fc->max_pages_limit (and, for virtio-fs, by the virtqueue descriptor count), so io_pages inherits the same bound. Suggested-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Jim Harris <jim.harris@nvidia.com> Assisted-by: Cursor:claude-opus-4.8 Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-07-17UDF symlink pathComponent header OOB readDavid Lee1-0/+2
udf_symlink_filler() can enter udf_pc_to_char() with a partial pathComponent header. Validate that enough input remains for a complete pathComponent header before accessing it. Reject malformed symlink data that would otherwise make udf_pc_to_char() perform an out-of-bounds read. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: David Lee <david.lee@trailofbits.com> Assisted-by: Codex:gpt-5.5 Link: https://patch.msgid.link/20260717104722.41446-1-david.lee@trailofbits.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-17fuse: publish io-uring queues with release semanticsJoanne Koong1-9/+11
fuse_uring_create_queue() initializes a fuse_ring_queue and then publishes the pointer into ring->queues[qid] with WRITE_ONCE() under the fch->lock. There are several readers that may concurrently be fetching that pointer locklessly and then deferencing it. WRITE_ONCE() doesn't ensure ordering of the queue's field initialization before the ring->queues[qid] pointer assignment. The queue must be published with smp_store_release() so the field initialization is guaranteed to happen before. Readers in paths where the read may happen concurrently with the store need to use READ_ONCE() because any race involving a plain access is undefined. Fixes: 24fe962c86f5 ("fuse: {io-uring} Handle SQEs - register commands") Cc: stable@vger.kernel.org Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-07-17fuse: use release/acquire for fch->initializedJoanne Koong3-10/+11
fuse_chan_set_initialized() sets values for the connection state and then sets fch->initialized to true, but lockless readers read fch->initialized and if true, go to read the connection state values, without using any barriers. There are a few instances where this happens (fuse_uring_cmd() before dispatching register / commit-and-fetch cmds, fuse_dev_do_wriite() for handling notify retrieves, etc). To make this as simple as possible, use release/acquire semantics for writing/reading fch->initialized. Add the missing read barriers. This is not marked for stable as these are not realistically reachable on a well-behaved server, and buggy/malicious servers who trigger this path fail benignly rather than crash or deadlock the kernel. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-07-17fuse: fix missing barrier when checking io-uring readinessJoanne Koong1-4/+7
fuse_block_alloc() reads fch->initialized and then fch->io_uring. fch->io_uring is set before fch->initialized, ordered by the smp_wmb() in fuse_chan_set_intialized(), but fuse_block_alloc() has no matching read barrier between the two loads. This may lead a CPU to observe fch->initialized=1 but fch->io_uring=0, and skip the check that blocks request allocation until the io-uring queues are ready. This can reintroduce the lock-order inversion deadlock that commit 3393ff964e0f prevents. Add an smp_rmb() barrier to pair with the smp_wmb() in fuse_chan_set_initialized() to prevent this. Fixes: 3393ff964e0f ("fuse: block request allocation until io-uring init is complete") Cc: stable@vger.kernel.org Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-07-16Merge tag 'v7.2-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6Linus Torvalds11-56/+240
Pull smb client fixes from Steve French: - fallocate fixes - unit test fixes - fix allocation size after duplicate extents - fix check for overlapping data areas * tag 'v7.2-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb/client: flush dirty data before punching a hole smb/client: Use EXPORT_SYMBOL_IF_KUNIT() to export symbols in SMB2 smb/client: Use EXPORT_SYMBOL_IF_KUNIT() to export symbols smb: client: reject overlapping data areas in SMB2 responses smb/client: refresh allocation after EOF-extending fallocate smb/client: emulate small EOF-extending mode 0 fallocate ranges smb/client: reduce fallocate zero buffer allocation smb/client: handle overlapping allocated ranges in fallocate smb/client: refresh allocation size after duplicate extents smb: client: use kvzalloc() for megabyte buffer in simple fallocate
2026-07-16Merge tag 'xfs-fixes-7.2-rc4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linuxLinus Torvalds21-167/+338
Pull xfs fixes from Carlos Maiolino: "This contains mostly a series of bug fixes found by different LLM models" * tag 'xfs-fixes-7.2-rc4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (21 commits) xfs: don't zap bmbt forks if they are MAXLEVELS tall xfs: clamp timestamp nanoseconds correctly xfs: fully check the parent handle when it points to the rootdir xfs: handle non-inode owners for rtrmap record checking xfs: fix off-by-one error when calling xchk_xref_has_rt_owner xfs: set xfarray killable sort correctly xfs: grab rtrmap btree when checking rgsuper xfs: write the rg superblock when fixing it xfs: use the rt version of the cow staging checker xfs: use rtrefcount btree cursor in xchk_xref_is_rt_cow_staging xfs: don't wrap around quota ids in dqiterate xfs: move cow_replace_mapping to xfs_bmap_util.c xfs: make cow repair somewhat flaky when debugging knob enabled xfs: don't replace the wrong part of the cow fork xfs: resample the data fork mapping after cycling ILOCK xfs: fix null pointer dereference in tracepoint xfs: use xfs_csn_t for xlog_cil_push_now() push_seq parameter xfs: tie zoned sysfs lifetime to zone info xfs: fail recovery on a committed log item with no regions xfs: splice unsorted log items back to the transaction after the loop ...
2026-07-16Merge tag 'erofs-for-7.2-rc4-fixes' of ↵Linus Torvalds3-22/+8
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs fixes from Gao Xiang: - Fix sanity checks for ztailpacking tail pclusters to avoid false corruption reports - Use more informative s_id for file-backed mounts - Hide the meaningless "cache_strategy=" mount option on plain (uncompressed) filesystems - Remove the unneeded erofs_is_ishare_inode() helper * tag 'erofs-for-7.2-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: hide "cache_strategy=" for plain filesystems erofs: get rid of erofs_is_ishare_inode() helper erofs: relax sanity check for tail pclusters due to ztailpacking erofs: use more informative s_id for file-backed mounts
2026-07-16ksmbd: validate compound request size before reading StructureSize2Xiang Mei (Microsoft)1-0/+5
When ksmbd validates a compound (chained) SMB2 request, ksmbd_smb2_check_message() reads pdu->StructureSize2 without first checking that the compound element is large enough to contain it. StructureSize2 is a 2-byte field at offset 64 (__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element. The compound-walking logic only guarantees that a full 64-byte SMB2 header is present for the trailing element: when NextCommand is 0, len is reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A remote client can craft a compound request whose last element has exactly 64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte past the receive buffer, producing a slab-out-of-bounds read. BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14 The buggy address is located 172 bytes inside of allocated 173-byte region Workqueue: ksmbd-io handle_ksmbd_work Call Trace: ... kasan_report (mm/kasan/report.c:595) ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) handle_ksmbd_work (fs/smb/server/server.c:119) process_one_work (kernel/workqueue.c:3314) worker_thread (kernel/workqueue.c:3397) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Reject any compound element that is too small to hold StructureSize2 before dereferencing it. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: AutonomousCodeSecurity@microsoft.com Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: lock the binding preauth session in smb3_preauth_hash_rspGil Portnoy1-10/+9
smb3_preauth_hash_rsp() computes the SMB3.1.1 preauth integrity hash on the response path. For a binding SESSION_SETUP it looks up the per-connection preauth_session and reads its Preauth_HashValue. smb2_sess_setup() frees that preauth_session under ksmbd_conn_lock(). Two SMB2 requests on one connection can run concurrently, so an unlocked lookup and hash can use a preauth_session after another worker frees it. Take ksmbd_conn_lock() before selecting conn->binding and hold it across the selected preauth hash lookup and update. This preserves the existing hash selection while preventing the lookup-to-use lifetime race. Fixes: 1c5daa2ea924 ("ksmbd: handle channel binding with a different user") Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: remove stale channels from all sessions on teardownGil Portnoy1-14/+11
ksmbd_sessions_deregister() removes a connection's channels from other sessions' channel lists only while conn->binding is still set: if (conn->binding) { hash_for_each_safe(sessions_table, ...) ksmbd_chann_del(conn, sess); } conn->binding is a transient flag: it is cleared once a binding SESSION_SETUP completes, and also by a subsequent non-binding SESSION_SETUP on the same connection (a reauthentication on a bound channel, or a new SessionId==0 setup). A connection that has bound a channel into another session's ksmbd_chann_list and then clears conn->binding leaves that channel behind when it disconnects: the channel, whose chann->conn points at the now freed struct ksmbd_conn, stays on the owner session's list. When the owning connection later tears down, the second loop dereferences the stale channel: xa_for_each(&sess->ksmbd_chann_list, chann_id, chann) if (chann->conn != conn) ksmbd_conn_set_exiting(chann->conn); /* freed */ which is a use-after-free write into the freed ksmbd_conn (the same stale channel is also walked by show_proc_session() through /proc). The session is leaked as well, because its channel list never empties. Remove the conn->binding gate so a connection always removes its channels from every session on teardown. Fixes: faf8578c77f3 ("ksmbd: find bound sessions during reauthentication") Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: fix stack buffer overflow in multichannel session-key copyGil Portnoy2-3/+3
Commit 4b706360ffb7 ("ksmbd: fix multichannel binding and enforce channel limit") moved the binding-path session key out of the session-wide sess->sess_key (CIFS_KEY_SIZE = 40) into a new per-channel buffer, and sized both that buffer and the on-stack copy used during binding with SMB2_NTLMV2_SESSKEY_SIZE (16): struct channel { char sess_key[SMB2_NTLMV2_SESSKEY_SIZE]; /* 16 */ ... }; ntlm_authenticate() / krb5_authenticate(): char channel_key[SMB2_NTLMV2_SESSKEY_SIZE] = {}; /* 16 */ char *auth_key = conn->binding ? channel_key : sess->sess_key; The two writers that fill this destination still bound the copy length against CIFS_KEY_SIZE (40), not against the 16-byte buffer: ksmbd_decode_ntlmssp_auth_blob() (NTLM key exchange): if (sess_key_len > CIFS_KEY_SIZE) /* 40 */ return -EINVAL; arc4_crypt(ctx_arc4, sess_key, (char *)authblob + sess_key_off, sess_key_len); ksmbd_krb5_authenticate(): if (resp->session_key_len > sizeof(sess->sess_key)) /* 40 */ ... memcpy(sess_key, resp->payload, resp->session_key_len); On a binding SESSION_SETUP, auth_key points at the 16-byte channel_key, so a client that supplies an NTLM EncryptedRandomSessionKey of up to 40 bytes (with NTLMSSP_NEGOTIATE_KEY_EXCH), or a Kerberos ticket whose session key is longer than 16 bytes (a normal AES256 key is 32), writes past the 16-byte stack buffer -- up to a 24-byte kernel stack overflow. KASAN reports it as a stack-out-of-bounds write in arc4_crypt() called from ksmbd_decode_ntlmssp_auth_blob(). The destinations must be able to hold the full session key the length checks already permit. Size the per-channel key buffer and the two on-stack channel_key buffers with CIFS_KEY_SIZE, matching sess->sess_key. Fixes: 4b706360ffb7 ("ksmbd: fix multichannel binding and enforce channel limit") Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: fix memory leak of xattr_stream_name in smb2_rename()Gil Portnoy1-2/+1
On an SMB2 SET_INFO(FileRenameInformation) whose target names an alternate data stream, smb2_rename() obtains a formatted stream-name string from ksmbd_vfs_xattr_stream_name(), which allocates it with kasprintf() and returns it through an out-param: rc = ksmbd_vfs_xattr_stream_name(stream_name, &xattr_stream_name, ...); if (rc) goto out; rc = ksmbd_vfs_setxattr(..., xattr_stream_name, ...); if (rc < 0) { ... goto out; } goto out; xattr_stream_name is declared inside the alternate-data-stream block, but the out: label is outside that block and frees only new_name, so it cannot release xattr_stream_name. ksmbd_vfs_setxattr() takes a const char * and only reads the name, so it does not take ownership either. Both the setxattr-failure and the success path therefore leak the kasprintf()'d string. An authenticated client with a writable share can leak kernel memory on every stream rename, exhausting kernel memory over time. Free xattr_stream_name after its use, before the block's goto out. The two earlier goto out paths never assign the variable, so there is no double-free. Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: zero the smb2_read alignment tail to avoid an infoleakGil Portnoy1-0/+9
Commit 6b9a2e09d4cc ("ksmbd: avoid zeroing the read buffer in smb2_read()") switched the SMB2 READ payload buffer from kvzalloc() to kvmalloc(), on the premise that only the nbytes actually read are ever transmitted, so the ALIGN(length, 8) tail need not be initialized. That premise does not hold for a compound response. ksmbd_vfs_read() fills only nbytes, leaving [nbytes, ALIGN(length, 8)) uninitialized. The aux payload is pinned as the last response iov with iov_len == nbytes, but when the READ is a member of a compound, init_chained_smb2_rsp() 8-byte-aligns the previous member by extending that same iov: new_len = ALIGN(len, 8); work->iov[work->iov_idx].iov_len += (new_len - len); inc_rfc1001_len(work->response_buf, new_len - len); so up to 7 uninitialized bytes of the kvmalloc()'d slab tail are sent to the client. When the read length is small the buffer is served from a general kmalloc slab, so those bytes can be stale kernel-heap contents, including pointer values -- an information leak usable to defeat KASLR. An authenticated client triggers it with a compound request containing a READ whose returned nbytes is not 8-aligned (for example [READ, CLOSE] with a 1-byte read). Zero only the alignment tail after the read, preserving the bulk no-zeroing optimization of 6b9a2e09d4cc. Fixes: 6b9a2e09d4cc ("ksmbd: avoid zeroing the read buffer in smb2_read()") Cc: stable@vger.kernel.org Signed-off-by: Gil Portnoy <dddhkts1@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: pin conn during async oplock break notificationQihang1-2/+4
smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn pointer in an async ksmbd_work and then queue that work on ksmbd-io. The work only increments conn->r_count, which prevents teardown from passing the pending-request wait after the increment, but it does not pin the struct ksmbd_conn object. If connection teardown races with an oplock break notification, the last conn reference can be dropped before the queued worker finishes. The worker then uses the freed conn in ksmbd_conn_write() and ksmbd_conn_r_count_dec(). Take a real conn reference when publishing the conn pointer to the async work item, and drop it after the notification work has decremented r_count. Apply the same lifetime rule to lease break notification, which uses the same work->conn pattern. Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification") Signed-off-by: Qihang <q.h.hack.winter@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-16ksmbd: fix integer overflow in set_file_allocation_info()Ibrahim Hashimov1-1/+14
set_file_allocation_info() converts the client-supplied FILE_ALLOCATION_INFORMATION::AllocationSize into a 512-byte block count with: alloc_blks = (le64_to_cpu(file_alloc_info->AllocationSize) + 511) >> 9; AllocationSize is a fully client-controlled __le64 field; the only validation performed by the caller (smb2_set_info_file(), case FILE_ALLOCATION_INFORMATION) is that the fixed buffer is at least sizeof(struct smb2_file_alloc_info) == 8 bytes. The value itself is never range-checked before this arithmetic. When AllocationSize is close to U64_MAX (e.g. 0xffffffffffffffff), "AllocationSize + 511" wraps around mod 2^64 to a small number (0xffffffffffffffff + 511 = 510), so alloc_blks becomes 0. Since any existing regular file has stat.blocks > 0, the function then takes the "shrink" branch and calls: ksmbd_vfs_truncate(work, fp, alloc_blks * 512); /* == 0 */ silently truncating the file to size 0, even though the client asked to grow the allocation to (what looks like) the maximum possible size. The trailing "if (size < alloc_blks * 512) i_size_write(inode, size);" restore is guarded by a comparison that is never true once alloc_blks == 0, so the truncation is not undone. This lets an authenticated SMB client that already holds an open handle with FILE_WRITE_DATA on a file silently truncate that same file to size 0 via a single crafted SET_INFO(FILE_ALLOCATION_INFORMATION) request advertising a near-U64_MAX AllocationSize, even though the request asks to grow the file's allocation rather than shrink it. This is a functional/data-loss bug, not a privilege-boundary violation: the same client could already truncate the file via FILE_END_OF_FILE_INFORMATION or a plain write. Fix it by validating AllocationSize against MAX_LFS_FILESIZE, the same upper bound the VFS itself uses to reject unrepresentable file sizes, before doing the "+511" rounding, and rejecting oversized values with -EINVAL. Bounding AllocationSize to MAX_LFS_FILESIZE - 511 guarantees the "+511" addition cannot wrap, and that the subsequent "alloc_blks * 512" values passed to vfs_fallocate() and ksmbd_vfs_truncate() stay within a representable loff_t as well. No legitimate SMB client asks for an allocation size anywhere near 2^64 bytes, so this only rejects a value that was previously silently misinterpreted as zero. Runtime-verified on a v6.19 KASAN test stand: sending SET_INFO (FILE_ALLOCATION_INFORMATION) with AllocationSize = 0xffffffffffffffff against ksmbd now returns -EINVAL and leaves the target file's size unchanged, where the unpatched kernel truncated it from 4096 to 0 bytes. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-14smb/client: flush dirty data before punching a holeHuiwen He1-0/+9
Punching a hole after a large buffered write may leave the range reported as data. Reproduce it with: xfs_io -f \ -c "pwrite -b 3m -S 0x61 0 3m" \ -c "fpunch 1m 1m" \ -c "seek -h 0" \ -c "seek -d 1m" \ /mnt/test/repro Punching 1 MiB at offset 1 MiB should produce: 0 1 MiB 2 MiB 3 MiB | DATA | HOLE | DATA | EOF Instead, the entire file is reported as data. SEEK_HOLE(0) returns EOF, and SEEK_DATA(1M) returns 1M. This happens because a dirty folio spanning the punched range can be written back after the punch and refill the hole. Fix this by flushing and waiting for dirty data in the punched range before invalidating the page cache and issuing FSCTL_SET_ZERO_DATA. The xfstests generic/539 pass against Samba/ksmbd with this change. Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-14smb/client: Use EXPORT_SYMBOL_IF_KUNIT() to export symbols in SMB2Andy Shevchenko2-6/+7
Replace EXPORT_SYMBOL_FOR_MODULES() with EXPORT_SYMBOL_IF_KUNIT() to mark the symbols as visible only if CONFIG_KUNIT is enabled. Kunit test should import the namespace EXPORTED_FOR_KUNIT_TESTING to use these marked symbols. This is the standard way for all KUnit tests. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-14smb/client: Use EXPORT_SYMBOL_IF_KUNIT() to export symbolsAndy Shevchenko2-12/+13
Replace EXPORT_SYMBOL_FOR_MODULES() with EXPORT_SYMBOL_IF_KUNIT() to mark the symbols as visible only if CONFIG_KUNIT is enabled. Kunit test should import the namespace EXPORTED_FOR_KUNIT_TESTING to use these marked symbols. This is the standard way for all KUnit tests. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-14dax: fix misleading comment about share/index union in dax_folio_reset_order()John Groves1-6/+6
The comment in dax_folio_reset_order() claims that DAX maintains an invariant where folio->share != 0 only when folio->mapping == NULL, implying folio->share is zero whenever mapping is non-NULL. This is misleading because folio->share and folio->index are a union -- for non-shared folios with mapping != NULL, reading folio->share returns the file page offset (folio->index), which is typically non-zero. Reword the comment to accurately describe the union aliasing: the assignment clears whichever interpretation of the union word is active (index for non-shared folios, share for shared folios), which is correct because the folio is being released in either case. No functional change -- the code was already correct, only the justification was wrong. Fixes: 59eb73b98ae0b ("dax: Factor out dax_folio_reset_order() helper") Reviewed-by: Jonathan Cameron <jic23@kernel.org> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc08b8cd-4ee80eeb-1341-4f67-8478-7298129440e9-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14hfs: don't re-dirty MDB buffers after a write failureViacheslav Dubeyko3-6/+27
hfs_mdb_commit() and hfs_mdb_close() keep the MDB and alternate-MDB buffer heads (mdb_bh, alt_mdb_bh) pinned for the lifetime of the mount and write into them in place. If a write against the backing device fails, the block layer clears BH_Uptodate on the buffer (end_buffer_write_sync(), fs/buffer.c) to mark its contents as no longer trustworthy. !buffer_uptodate(bh) WARNING: fs/buffer.c:1093 at mark_buffer_dirty+0x299/0x410 fs/buffer.c:1093, CPU#0: syz.1.1033/6784 Modules linked in: CPU: 0 UID: 0 PID: 6784 Comm: syz.1.1033 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:mark_buffer_dirty+0x299/0x410 fs/buffer.c:1093 Code: 4c 89 f7 e8 f9 0d d9 ff 49 8b 3e be 40 00 00 00 5b 41 5c 41 5e 41 5f 5d e9 d4 5e fb ff e8 af e7 69 ff eb 8c e8 a8 e7 69 ff 90 <0f> 0b 90 e9 a5 fd ff ff e8 9a e7 69 ff 90 0f 0b 90 e9 cf fd ff ff RSP: 0018:ffffc90005d379a8 EFLAGS: 00010293 RAX: ffffffff825c9ae8 RBX: ffff8880123aa700 RCX: ffff888034a30000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002 RBP: 1ffff1100a45f401 R08: ffff8880123aa707 R09: 1ffff110024754e0 R10: dffffc0000000000 R11: ffffed10024754e1 R12: dffffc0000000000 R13: ffff8880522fa668 R14: ffff888045ba945b R15: ffff888045ba9400 FS: 000055556b366500(0000) GS:ffff88808c54e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b31a63fff CR3: 0000000034b1d000 CR4: 0000000000352ef0 Call Trace: <TASK> hfs_mdb_commit+0x503/0x1160 fs/hfs/mdb.c:309 hfs_sync_fs+0x1d/0x30 fs/hfs/super.c:38 sync_filesystem+0x1cf/0x230 fs/sync.c:66 fs_bdev_sync+0x2c/0x50 fs/super.c:1433 blkdev_flushbuf block/ioctl.c:520 [inline] blkdev_common_ioctl+0x12e1/0x3250 block/ioctl.c:658 blkdev_ioctl+0x528/0x740 block/ioctl.c:791 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f1d9239de59 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fffd0ece148 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f1d92625fa0 RCX: 00007f1d9239de59 RDX: 0000000000000000 RSI: 0000000000001261 RDI: 0000000000000004 RBP: 00007f1d92433e6f R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f1d92625fac R14: 00007f1d92625fa0 R15: 00007f1d92625fa0 </TASK> This was found by fuzzing an HFS image on a loop device backed by a memfd; under memory pressure the shmem write-back path returned -ENOSPC (mm/shmem.c, shmem_acct_blocks()), which surfaced as a plain write error on the block device. The call path: ioctl(BLKFLSBUF) -> blkdev_common_ioctl() -> sync_filesystem() -> hfs_sync_fs() -> hfs_mdb_commit(). Check buffer_uptodate() on mdb_bh/alt_mdb_bh before dirtying them. If either has gone stale, mark the volume read-only and skip the write instead of asserting on it. Also, hfs_mdb_commit() returns -EIO error code in such situation. As a result, hfs_sync_fs() can report the failure instead of always returning 0. The sync()/fsync()/BLKFLSBUF now observe -EIO instead of silently succeeding while the volume goes read-only underneath them. Reported-by: syzbot+c149ad75e9633be0c1ad@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c149ad75e9633be0c1ad cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> cc: Yangtao Li <frank.li@vivo.com> cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260709225001.473320-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-14hfsplus: fix error code when writing beyond volume capacityViacheslav Dubeyko1-1/+9
The xfstests' test-case generic/564 fails for the case of HFS+ file system. Test-case expects that file system driver reports -EFBIG error code in the case if there is the effort to write beyond 8TiB. However, HFS+ file system driver returns -ENOSPC instead. The root cause is that hfsplus_fill_super() sets s_maxbytes as MAX_LFS_FILESIZE. VFS therefore considers the write position valid and calls into the filesystem. Because HFS+ does not support holes, cont_write_begin() zero-fills the entire intermediate range from the current end-of-file to the target offset. On a small test volume this exhausts free space long before any block-number overflow is detected, producing -ENOSPC instead of -EFBIG. This patch fixes the issue by adding a bounds check at the top of hfsplus_write_begin(). If the requested write position is at or beyond the actual capacity of the volume in bytes, return -EFBIG immediately before cont_write_begin() is entered and before any zero-fill I/O is attempted. sudo ./check generic/564 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.2.0-rc1-dirty #50 SMP PREEMPT_DYNAMIC Fri Jul 3 16:22:27 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/564 13s ... 43s Ran: generic/564 Passed all 1 tests cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> cc: Yangtao Li <frank.li@vivo.com> cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260706221738.140271-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-14hfs: fix error code when writing beyond volume capacityViacheslav Dubeyko1-1/+9
Likewise HFS+, HFS has the same issue of returning the -ENOSPC error code instead of -EFBIG in the case if there is the effort to write beyond 8TiB. The root cause is that hfs_fill_super() sets s_maxbytes as MAX_LFS_FILESIZE. VFS therefore considers the write position valid and calls into the filesystem. Because HFS does not support holes, cont_write_begin() zero-fills the entire intermediate range from the current end-of-file to the target offset. On a small test volume this exhausts free space long before any block-number overflow is detected, producing -ENOSPC instead of -EFBIG. This patch fixes the issue by adding a bounds check at the top of hfs_write_begin(). If the requested write position is at or beyond the actual capacity of the volume in bytes, return -EFBIG immediately before cont_write_begin() is entered and before any zero-fill I/O is attempted. cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> cc: Yangtao Li <frank.li@vivo.com> cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260706221804.140295-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-14hfsplus: validate thread record before delete key rebuildKyle Zeng2-13/+18
hfsplus_delete_cat() is called with str == NULL when the last open reference to an unlinked HFS+ hardlink backing inode is closed. In that case, the function finds the catalog thread by CNID and rebuilds the catalog key from thread.nodeName. That reconstruction path reads thread.nodeName.length directly from the catalog B-tree into fd.search_key and then copies length * 2 bytes into fd.search_key->cat.name.unicode. It does not first check that the found record is a thread record or that its size matches the thread name. A corrupted image can therefore provide an oversized thread name length and make hfs_bnode_read() write past the catalog search-key allocation. Read the CNID record through hfsplus_brec_read_cat(), which bounds the record read to sizeof(hfsplus_cat_entry) and verifies that a thread record's size exactly matches nodeName.length. Together, these checks ensure an accepted thread name fits HFSPLUS_MAX_STRLEN. Reject non-thread records before building the delete key from the validated thread name. Share the thread-record-type helper between hfsplus_find_cat() and hfsplus_delete_cat(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: Codex:gpt-5.6 Signed-off-by: Kyle Zeng <kylebot@openai.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260709010203.49664-1-kylebot@openai.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-14hfs: validate catalog CNIDs before instantiating inodesDavid Maximiliano Hermitte4-2/+76
hfs_cat_find_brec() first resolves a catalog thread record by CNID and then looks up the corresponding catalog record by parent/name. On a corrupted filesystem image, the second lookup may find a record whose CNID does not match the CNID that was requested. Validate the record found by the second lookup before returning it. Read the already-found record with hfs_bnode_read(), require the exact fixed size for file and directory records, reject other record types, and verify that the stored CNID matches the requested CNID. Also validate reserved CNIDs in hfs_read_inode() before populating the inode, propagate hfs_read_inode() failures from the resource-fork lookup path, and reject bad resource-fork and root inodes. Keep hfs_write_inode() unchanged, so corrupted catalog records are rejected before reaching its existing reserved-CNID BUG() path. Reported-by: syzbot+97e301b4b82ae803d21b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=97e301b4b82ae803d21b Cc: George Anthony Vernon <contact@gvernon.com> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: David Maximiliano Hermitte <davemadmaxxx@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260708215636.73815-1-davemadmaxxx@gmail.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-14fs/ntfs3: fix slab-out-of-bounds write in ni_create_attr_list()HE WEI(ギカク)1-4/+16
ni_create_attr_list() allocates a fixed buffer of al_aligned(record_size) (== record_size) bytes and then walks every attribute of the primary MFT record, writing one ATTR_LIST_ENTRY per attribute and advancing the cursor by le_size(name_len), with no check against the end of the buffer; the total size is only computed after the loop. A minimum-size resident attribute occupies SIZEOF_RESIDENT (0x18 = 24) bytes on disk, but an unnamed attribute expands to le_size(0) (0x20 = 32) bytes in the list. Because the number of attributes in a record is not bounded (mi_enum_attr() accepts arbitrarily many equal-type, nameless minimum-size attributes), a crafted record packed with such attributes produces a list larger than record_size and overflows the heap buffer. This is reachable from a crafted, loop-mounted NTFS image: opening the file and adding an attribute (e.g. via setxattr) drives ntfs_set_ea() -> ni_insert_resident() -> ni_insert_attr() -> ni_ins_attr_ext() -> ni_create_attr_list(). BUG: KASAN: slab-out-of-bounds in ni_create_attr_list+0xc48/0x1058 Write of size 4 at addr ffff000008984c00 by task setfattr/345 ni_create_attr_list+0xc48/0x1058 ni_ins_attr_ext+0x510/0x7c0 ni_insert_attr+0x3f8/0x70c ni_insert_resident+0xc8/0x3b0 ntfs_set_ea+0x66c/0xd28 ntfs_setxattr+0x4d8/0x5b0 __arm64_sys_setxattr+0xa4/0x124 Allocated by task 345: ni_create_attr_list+0x188/0x1058 The buggy address belongs to the cache kmalloc-1k of size 1024 (the write lands at object+1024). Size the buffer from the actual attributes instead of assuming a single record_size is always enough. Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") Reported-by: HE WEI(ギカク) <skyexpoc@gmail.com> Signed-off-by: HE WEI(ギカク) <skyexpoc@gmail.com> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-14fs/ntfs3: cosmetic fixes and improvementsKonstantin Komarov11-36/+34
Get rid of unnecessary duplications, improve readability, clang-format the code. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-14fs/ntfs3: widen inode/record number storage to u64Konstantin Komarov3-9/+9
NTFS inode and MFT record numbers are inherently 64-bit values, but several places stored them in 'unsigned long' (or CLST, a u32). On 32-bit architectures 'unsigned long' is only 32 bits wide, so the upper bits of a record reference are truncated. Store these values in u64 and update the associated format specifiers (%lx -> %llx) accordingly. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-14Merge tag 'for-7.2-rc3-tag' of ↵Linus Torvalds8-25/+82
git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: - fix root structure leak after relocation error - fix optimization when checksums are read from commit root, fall back to checksum root during relocation - in tree-checker, validate length of inode reference in items - validate properties before setting them - validate free space cache entries on load - transaction abort fixes - fix printing of internal trees as signed numbers - add error messages after critical lzo compression errors * tag 'for-7.2-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: print-tree: print header owner as signed btrfs: decentralize transaction aborts in create_reloc_root() btrfs: tree-checker: validate INODE_REF's namelen btrfs: lzo: add error message for invalid headers btrfs: fallback to transaction csum tree on a commit root csum miss btrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots() btrfs: reject free space cache with more entries than pages btrfs: fix transaction abort logic in btrfs_fileattr_set() btrfs: validate properties before setting them
2026-07-14xfs: don't zap bmbt forks if they are MAXLEVELS tallDarrick J. Wong1-1/+1
LOLLM noticed a discrepancy between the bmbt level checks in the libxfs bmbt code vs. the inode repair code. We do actually allow a bmbt root that proclaims to have a height of XFS_BM_MAXLEVELS. Cc: stable@vger.kernel.org # v6.8 Fixes: e744cef2060559 ("xfs: zap broken inode forks") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: clamp timestamp nanoseconds correctlyDarrick J. Wong1-1/+1
LOLLM noticed an off-by-one error in the nsec clamping; fix that so that we never have tv_nsec == 1e9. Cc: stable@vger.kernel.org # v6.8 Fixes: 2d295fe65776d1 ("xfs: repair inode records") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: fully check the parent handle when it points to the rootdirDarrick J. Wong1-8/+8
LOLLM noticed that the directory tree path checking declares the path to be ok if the inumber in the parent pointer reaches the root directory. Unfortunately, it neglects to check that the generation is correct. Fix that by moving the generation check up. Cc: stable@vger.kernel.org # v6.10 Fixes: 928b721a11789a ("xfs: teach online scrub to find directory tree structure problems") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: handle non-inode owners for rtrmap record checkingDarrick J. Wong1-0/+6
LOLLM noticed that two helper functions in the rtrmapbt scrub code don't actually handle non-inode owners correctly -- CoW staging extents and rgsuperblock extents are not shareable, but they are mergeable. Fix these two helpers. Cc: stable@vger.kernel.org # v6.14 Fixes: 2d9a3e98053e8c ("xfs: allow overlapping rtrmapbt records for shared data extents") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: fix off-by-one error when calling xchk_xref_has_rt_ownerDarrick J. Wong1-1/+1
LOLLM noticed an off-by-one error when computing the length of the rtrmap to cross-check. Cc: stable@vger.kernel.org # v6.14 Fixes: 037a44d8277adf ("xfs: cross-reference the realtime rmapbt") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: set xfarray killable sort correctlyDarrick J. Wong2-5/+4
LOLLM noticed that we *disable* interruptible sorts when the KILLABLE flag is set. This is backwards. Fix the incorrect logic, and rename the variable to make the connection more obvious. Cc: stable@vger.kernel.org # v6.10 Fixes: 271557de7cbfde ("xfs: reduce the rate of cond_resched calls inside scrub") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: grab rtrmap btree when checking rgsuperDarrick J. Wong1-1/+9
LOLLM noticed that we aren't grabbing the rtrmap btree when we check the realtime group superblock. As a result, none of the cross-referencing checks have ever run. Fix this. Cc: stable@vger.kernel.org # v6.14 Fixes: 428e4884656db9 ("xfs: allow queued realtime intents to drain before scrubbing") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-14xfs: write the rg superblock when fixing itDarrick J. Wong1-0/+4
The rtgroup superblock fixer should write the rtgroup superblock. LOLLM noticed this, oops. :/ Cc: stable@vger.kernel.org # v6.13 Fixes: 1433f8f9cead37 ("xfs: repair realtime group superblock") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>