summaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
2026-07-22ksmbd: restore DACL size on check_add_overflow() to avoid malformed ACLWentao Guan1-1/+6
check_add_overflow() unconditionally writes the truncated sum into *d even on overflow, per its contract in include/linux/overflow.h. The four check_add_overflow() guards in set_posix_acl_entries_dacl() and set_ntacl_dacl() break out of the ACE-building loops on overflow, but the truncated *size is then consumed downstream at the end of set_ntacl_dacl(): pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size); This produces an on-wire NT ACL whose pndacl->size under-reports the bytes actually written by the preceding fill_ace_for_sid()/memcpy() calls, yielding a malformed ACL that can trigger out-of-bounds reads when re-parsed by clients or ksmbd itself. Restore *size to its pre-addition value on each overflow branch (via `*size -= ace_sz` / `size -= nt_ace_size`) so that after the break, *size once again holds the cumulative size of the successfully-written ACEs. The committed ACL is then truncated-but-self-consistent rather than malformed. The ksmbd DACL builders are the only check_add_overflow() sites found where an overflow path breaks out of a loop and the destination value is consumed afterward. The other nearby break-style cases either return -EINVAL on overflow (transport_ipc.c) or break without consuming the overflowed destination value afterward (buildid.c). Fixes: 299f962c0b02 ("ksmbd: use check_add_overflow() to prevent u16 DACL size overflow") Assisted-by: atomcode:glm-5.2 Assisted-by: Codex:gpt-5.5 Cc: stable@vger.kernel.org Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-22ksmbd: bound DACL dedup walk to copied ACEsNamjae Jeon1-6/+10
set_ntacl_dacl() can stop copying ACEs before consuming the full input DACL when size accounting overflows. When that happens, num_aces reflects only the ACEs that were actually copied into the output DACL, but set_posix_acl_entries_dacl() still receives nt_num_aces and uses it to walk the existing ACE array during dedup. That makes the dedup walk scan past the copied ACE array and inspect buffer tail that does not contain valid ACEs. Split the two meanings currently carried by the NT ACE count. Pass the number of copied NT ACEs to bound the dedup walk, and preserve the original "input DACL had NT ACEs" state separately for the Everyone/default ACL fallback. This keeps the dedup walk aligned with the ACEs that are actually present in the rebuilt DACL. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-22ksmbd: enforce signing required by the sessionNamjae Jeon2-3/+10
SMB2_FLAGS_SIGNED is controlled by the incoming request and only indicates that a signature accompanies that request. Do not use it to decide whether a signing-required session must authenticate the request. Reject an unsigned plaintext request before dispatch when the session requires signing. Continue to validate signatures on signed requests, including when signing is optional. Encrypted requests have already been authenticated during decryption. An OPLOCK_BREAK acknowledgment is a session request and is subject to the same signing rule, so do not exclude it from signed-request detection. Reported-by: Charles Vosburgh <trilobyte777@gmail.com> Tested-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-22ksmbd: preserve VFS inherited POSIX ACL maskNamjae Jeon1-25/+1
The VFS initializes a child's POSIX ACL from the parent's default ACL and the requested creation mode. Do not mutate the parent ACL or overwrite the child's VFS-computed access and default ACLs afterwards. This preserves restrictive ACL_MASK entries and prevents SMB object creation from widening effective permissions. Reported-by: Charles Vosburgh <trilobyte777@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-22pidfs: handle FS_IOC32_GETVERSION in compat ioctlLi Chen1-1/+15
FS_IOC32_GETVERSION has a distinct compat command encoding. Passing it through compat_ptr_ioctl() leaves pidfd_ioctl() unable to recognize the otherwise architecture-independent inode generation query. Translate the compat command to FS_IOC_GETVERSION before dispatching it through the native pidfd ioctl implementation. Signed-off-by: Li Chen <me@linux.beauty> Link: https://patch.msgid.link/20260716052822.1034228-1-me@linux.beauty Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-22ovl: check access to copy_file_range source with src mounter credsAmir Goldstein1-1/+15
Commit 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") allowed filesystems that implement the copy_file_range() f_op to decide if they want to access cross-sb copy from/to the same fs type. The same commit added checks to verify same sb copy for filesystems that implement ->copy_file_range() and do not support cross-sb copy at the time, namely, to ceph, fuse and nfs. The two remaining fs which implement ->copy_file_range(), cifs and overlayfs started to support cross-sb copy from this time. While overlayfs does support cross-sb copy when the two underlying files are on the same base fs, the copy operation on the two real files from two different overalyfs filesystems is performed with the mounter creds of the destination overlayfs and the read permission access hook for the source file was called with the wrong creds. This could cause either deny of access to copy which would otherwise be allowed (e.g. with splice) or allow read access to file which would otherwise be denied. Fix the latter case by explicitly verifying read access to source file with the source overlayfs mounter creds. The former case remains a quirk of cross-sb overlayfs copy, but userspace could fall back to regular copy so no harm done. Fixes: 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://patch.msgid.link/20260712122421.203113-1-amir73il@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-22proc: Fix broken error paths for namespace linksJann Horn1-1/+3
Don't return the return value of down_read_killable() (0) when a ptrace access check fails, return -EACCES as intended. Reported-by: Magnus Lindholm <linmag7@gmail.com> Closes: https://lore.kernel.org/r/20260706170735.2941493-1-linmag7@gmail.com Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn <jannh@google.com> Link: https://patch.msgid.link/20260706-procfs-ns-eacces-fix-v1-1-a69ab14c02e6@google.com Tested-by: Magnus Lindholm <linmag7@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-22xfs: use kmalloc_objs() instead of kmalloc() in xfs_da_grow_inode_intCihan Karadag1-2/+1
Convert open-coded kmalloc() multiplication to the modern kmalloc_objs() interface to improve type safety and prevent potential integer overflows. No functional changes are intended. Signed-off-by: Cihan Karadag <cihan.cihan@gmail.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: mark internal metadir file creation helpers staticJohannes Thumshirn2-7/+3
Now that there is xfs_metadir_create_file() mark xfs_metadir_start_create(), xfs_metadir_create() and xfs_metadir_cancel() as static and remove them from xfs_metadir.h. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: create rtgroup metadir inodes using xfs_metadir_create_fileJohannes Thumshirn1-32/+26
Now that we have xfs_metadir_create_file() use it in xfs_rtginode_create(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: create quota metadir inodes using xfs_metadir_create_fileJohannes Thumshirn1-28/+11
Now that we have xfs_metadir_create_file() use it in xfs_dqinode_metadir_create(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: add xfs_metadir_create_file helperJohannes Thumshirn2-21/+43
Factor the metadata inode create/commit/cleanup lifecycle out of xfs_metadir_mkdir into a reusable helper that takes an optional callback to initialize the new inode, and convert xfs_metadir_mkdir to it. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: add support for FALLOC_FL_WRITE_ZEROESPankaj Raghav3-4/+99
If the underlying block device supports the unmap write zeroes operation, this flag allows users to quickly preallocate a file with written extents that contain zeroes. This is beneficial for subsequent overwrites as it prevents the need for unwritten-to-written extent conversions, thereby significantly reducing metadata updates and journal I/O overhead, improving overwrite performance. Punch the range first so it becomes a hole, update the size via xfs_falloc_setsize() while it is still a hole (so its xfs_zero_range() skips it and avoids rezeroing), then convert it to written zeroed extents. A crash between the size update and the conversion is safe, as a hole within i_size reads back as zeroes. Co-developed-by: Lukas Herbolt <lukas@herbolt.com> Signed-off-by: Lukas Herbolt <lukas@herbolt.com> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: add an allocation mode to xfs_alloc_file_space()Pankaj Raghav3-8/+32
xfs_alloc_file_space() hardcodes XFS_BMAPI_PREALLOC to preallocate unwritten extents across a range. In preparation for FALLOC_FL_WRITE_ZEROES, add an explicit allocation mode argument, enum xfs_alloc_file_space_mode, and derive the xfs_bmapi flags from it. The only mode for now is XFS_ALLOC_FILE_SPACE_PREALLOC, which preallocates unwritten extents and marks the inode as preallocated exactly as before, so there is no functional change. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: mark nonzero sb_gquotino as corrupt on metadir filesystemsDarrick J. Wong1-1/+1
On a metadir filesystem, the superblock gquotino field is always zero because we find the quota inodes through the metadata directory tree. A nonzero value is therefore a corruption (as pointed out by LOLLM) so mark the failure as such. Cc: stable@vger.kernel.org # v6.13 Fixes: 06b20ef09ba163 ("xfs: check pre-metadir fields correctly") 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-22xfs: zero i_nlink before repair puts inode on unlinked listDarrick J. Wong1-1/+6
LOLLM observes that we don't reset i_nlink if we encounter a file with no parent that isn't on the unlinked list. This causes unnecessary assertion trips on debugging kernels and an inconsistent file, so let's fix that. Cc: stable@vger.kernel.org # v6.10 Fixes: 669dfe883c8e20 ("xfs: update the unlinked list when repairing link counts") 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-22xfs: rtsummary scrub should treat rtbitmap corruption errors as an xref errorDarrick J. Wong1-1/+1
LOLLM notes the discrepancy between the comment saying that this is an xref error and the code, which marks a (non-xref) corruption error. This appears to be a regression. Cc: stable@vger.kernel.org # v6.13 Fixes: e3088ae2dcae3c ("xfs: move RT bitmap and summary information to the rtgroup") 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-22xfs: fix transaction block reservation in xrep_rtbitmapDarrick J. Wong1-18/+28
LOLLM pointed out an inconsistency in the block reservation code in xrep_rtbitmap. The first is that the reservation computation is not consistent between the code that sets up the repair and the code that tries to avoid exceeding the transaction reservation once we know how big the rtbitmap really must be. As a result, the logic doesn't work. In fixing that, a second problem emerges: if we do readjust, we ask for the entire reservation all over again. We really only need the delta, so ask only for that. Fix all these problems by hoisting the computation to a trivial helper so that it gets used in both places. Cc: stable@vger.kernel.org # v6.14 Fixes: 8defee8dff2b20 ("xfs: online repair of realtime bitmaps for a realtime group") 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-22xfs: check cowextsize in xrep_inode_cowextsizeDarrick J. Wong1-1/+1
LOLLM points out that the function that corrects cowextsize should check i_cowextsize, not i_extsize. Cc: stable@vger.kernel.org # v6.14 Fixes: a9600db96f74af ("xfs: detect and repair misaligned rtinherit directory cowextsize hints") 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-22xfs: update BDI {io,ra}_pages values based on the RT device limitsChristoph Hellwig2-1/+59
When using XFS with a main device on an SSD that stores metadata and a RT device to store data on a HDD, we fail to take the I/O sizes for the RT device into accounting, leading to up to 5% slower read performance when using an SSD for metadata vs storing data and metadata on the HDD. Fix this up by taking the RT settings into account at mount an restoring the old settings at unmount time, unless the BDI settings have changed from those set by XFS. Reported-by: Filip Blagojevic <filip.blagojevic@wdc.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: handle NULL b_addr in xfs_buf_freeYun Zhou1-1/+1
When xfs_buf_alloc_backing_mem() fails, xfs_buf_free() is called with bp->b_addr still NULL. The code falls through to the folio_put path which calls virt_to_folio(NULL), dereferencing an invalid address and causing a kernel crash. Call Trace: xfs_buf_free+0x25f/0x510 xfs_buf_alloc+0xc98/0x19b0 xfs_buf_find_insert+0x55/0x14d0 xfs_buf_get_map+0x122b/0x17c0 xfbtree_init_leaf_block+0x11c/0x4a0 xfbtree_init+0x1bb/0x460 xrep_rmap_setup_scan+0x100/0x1f0 xrep_rmapbt+0x41/0xc0 Fix this by skipping folio_put() when bp->b_addr is NULL. Fixes: 5076a6040ca1 ("xfs: support in-memory buffer cache targets") Reported-by: syzbot+94c22d92f72f5a235b7d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=94c22d92f72f5a235b7d Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: bounds-check buffer log item's dirty bitmapIbrahim Hashimov1-16/+41
xlog_recover_do_reg_buffer() replays each dirty region described by a buffer log item's bitmap into the buffer read for that item: memcpy(xfs_buf_offset(bp, (uint)bit << XFS_BLF_SHIFT), item->ri_buf[i].iov_base, nbits << XFS_BLF_SHIFT); The destination offset (bit/nbits, from the logged dirty bitmap) and the buffer size (from the logged blf_len) are both attacker-controlled and otherwise unrelated, yet the only thing bounding the copy is an ASSERT(), which compiles away on production kernels. A crafted image logging a small blf_len together with a bitmap bit past the end of that buffer drives the memcpy() past the buffer's allocation, corrupting adjacent kernel heap during mount-time log recovery. This is reachable by anyone who can get a crafted image mounted -- the malicious-filesystem threat model XFS already guards against elsewhere. Turn the ASSERT() into a real XFS_IS_CORRUPT() check that aborts recovery of the buffer with -EFSCORRUPTED, consistent with the validate-and-fail idiom already used in xlog_recover_do_inode_buffer() and xfs_dquot_item_recover.c. xlog_recover_do_reg_buffer() therefore becomes STATIC int and its three callers propagate the error. Found and confirmed with KASAN on a CONFIG_XFS_DEBUG=n build: the crafted image trips a slab-out-of-bounds write before this change and fails recovery cleanly with -EFSCORRUPTED after it. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: fix off-by-one in rtrefcount btree root level validationXiang Mei1-2/+2
xfs_rtrefcountbt_compute_maxlevels() sets mp->m_rtrefc_maxlevels = min(d_maxlevels, r_maxlevels) + 1; where the trailing "+ 1" already accounts for the inode-root level, so the deepest valid on-disk root level is m_rtrefc_maxlevels - 1 and a cursor must satisfy bc_nlevels <= bc_maxlevels (= m_rtrefc_maxlevels). The two on-disk validation paths, xfs_rtrefcountbt_verify() and xfs_iformat_rtrefcount(), check the root level with ">" instead of ">=", so a crafted rtreflink (metadir + realtime + reflink) image whose /rtgroups/N.refcount inode has bb_level == m_rtrefc_maxlevels is accepted on mount. xfs_rtrefcountbt_init_cursor() then sets bc_nlevels = bb_level + 1, exceeding bc_maxlevels by one. Since the xfs_rtrefcountbt_cur slab object is sized for exactly bc_maxlevels entries, the first btree op on such a cursor indexes bc_levels[m_rtrefc_maxlevels] past the end of the object. This is reached by the first rtrefcount cursor built after mount, via log/CoW recovery (xfs_reflink_recover_cow() during xfs_mountfs()) or an FS_IOC_GETFSMAP over the realtime device. Reject a root level equal to m_rtrefc_maxlevels, matching the ">=" form already used by the sibling data-device refcount/rmap verifiers and the in-memory rtrmap verifier. BUG: KASAN: slab-out-of-bounds in xfs_btree_lookup (fs/xfs/libxfs/xfs_btree.c:2101) Write of size 2 at addr ffff888018391658 by task exploit/144 xfs_btree_lookup (fs/xfs/libxfs/xfs_btree.c:2101) xfs_btree_query_range (fs/xfs/libxfs/xfs_btree.c:5308) xfs_refcount_recover_cow_leftovers (fs/xfs/libxfs/xfs_refcount.c:2113) xfs_reflink_recover_cow (fs/xfs/xfs_reflink.c:1085) xlog_recover_finish (fs/xfs/xfs_log_recover.c:3551) xfs_mountfs (fs/xfs/xfs_mount.c:1158) xfs_fs_fill_super (fs/xfs/xfs_super.c:1940) get_tree_bdev_flags (fs/super.c:1634) vfs_get_tree (fs/super.c:1694) path_mount (fs/namespace.c:4161) __x64_sys_mount (fs/namespace.c:4367) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) The buggy address belongs to the cache xfs_rtrefcountbt_cur of size 216 The buggy address is located 8 bytes to the right of allocated 216-byte region [ffff888018391578, ffff888018391650) Kernel panic - not syncing: Fatal exception Cc: stable@vger.kernel.org # v6.14 Fixes: 9abe03a0e4f978 ("xfs: introduce realtime refcount btree ondisk definitions") Reported-by: Weiming Shi <bestswngs@gmail.com> Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: clear zapped attr fork state when bmap repair finds no attr forkQiang Ma1-0/+5
xfstests xfs/377 can make xfs_scrub repeatedly check and repair the attr block map after inode repair zaps an attr fork. When inode repair zaps an attr fork, it records XFS_SICK_INO_BMBTA_ZAPPED so that scrub/repair can revisit the attr fork block map. If the fork has been reset to an empty state and removed, BMBTA repair has no attr fork mappings to rebuild and can return success. The post-repair scrub then runs with XREP_ALREADY_FIXED set, which means xchk_file_looks_zapped() deliberately ignores the stale zapped health bit and asks xchk_bmap() to check the current attr fork. For an absent attr fork, xchk_bmap() returns -ENOENT. Returning that error prevents xchk_bmap_attr() from marking XFS_SICK_INO_BMBTA_ZAPPED healthy, leaving the zapped health state behind even though there are no attr fork mappings left to check. Treat -ENOENT during post-repair BMBTA revalidation as a clean result for the zapped attr fork: clear XFS_SICK_INO_BMBTA_ZAPPED and return success. Keep the existing -ENOENT behavior for ordinary scrubs of absent attr forks. Fixes: d9041681dd2f ("xfs: set inode sick state flags when we zap either ondisk fork") Cc: stable@vger.kernel.org # v6.8 Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Qiang Ma <maqianga@uniontech.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22pidfs: add pidfs_dentry_open() helperChristian Brauner1-21/+21
Both pidfs_alloc_file() and pidfs_export_open() need to force O_RDWR and reapply the pidfd flags that do_dentry_open() strips. Move the common logic into a helper. PIDFD_AUTOKILL is now part of the restore mask in the file handle path as well, but pidfs_export_permission() rejects O_TRUNC, so this is a no-op there. But warn nonetheless. Link: https://patch.msgid.link/20260722-esszimmer-umsetzen-nennt-ed5fc604300a@brauner Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-22pidfs: preserve thread pidfds reopened by file handleChristian Brauner1-1/+7
PIDFD_THREAD shares O_EXCL. do_dentry_open() clears O_EXCL after pidfs_export_open() validates the flags, so open_by_handle_at() silently turns a thread pidfd into a process pidfd. Restore PIDFD_THREAD on the opened file, matching pidfs_alloc_file(). Signed-off-by: Li Chen <me@linux.beauty> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260716052726.1032092-1-me@linux.beauty Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-22ovl: fix trusted xattr escape prefix matchingYichong Chen1-1/+1
In the trusted.* xattr namespace, ovl_is_escaped_xattr() compares one byte less than the escaped overlay xattr prefix length. This makes it match "trusted.overlay.overlay" without requiring the trailing dot. As a result, an xattr such as "trusted.overlay.overlayfoo" is incorrectly treated as an escaped overlay xattr. This can be reproduced by setting "trusted.overlay.overlayfoo" on a lower file and listing xattrs through an overlay mount. listxattr() then exposes it as "trusted.overlay.oo", and a following getxattr() on that listed name fails with ENODATA. Compare the full escaped prefix, including the trailing dot, so similarly-prefixed private xattrs are not misclassified. Fixes: dad02fad84cbc ("ovl: Support escaped overlay.* xattrs") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260708082221.633602-1-chenyichong@uniontech.com Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain pathsFrank Sorenson1-6/+39
In cifs_close_deferred_file(), cifs_close_all_deferred_files(), and cifs_close_deferred_file_under_dentry(), when a pending deferred close is cancelled via cancel_delayed_work(), the subsequent kmalloc_obj() to add the file to the local processing list may fail under memory pressure. The loop breaks immediately, but the cancelled work is no longer pending (it would have called _cifsFileInfo_put()), and the cfile is never added to file_head for processing. The cifsFileInfo reference and the open server handle both leak. Fix by saving the cfile that failed allocation in a local variable, breaking as before, and calling _cifsFileInfo_put() on it after releasing the lock. Any files later in the iteration are unaffected since their deferred work is still pending and will fire normally. Fixes: e3fc065682eb ("cifs: Deferred close performance improvements") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-21cifs: prevent readdir from changing file size due to stale directory metadataFrank Sorenson5-8/+96
Windows Server's directory enumeration metadata lags behind the actual file size after a write+close or rename. A concurrent readdir() in the window between close() returning to userspace and stat() being called overwrites the correct cached i_size with the stale server value, causing stat() to return the wrong size. Once _cifsFileInfo_put() removes the last writable handle from openFileList, is_size_safe_to_change() permits readdir to overwrite i_size. smb2_close_getattr() then stamps cifs_i->time = jiffies, making the corrupt cached value appear fresh to the next stat(). The existing check (see Fixes:) only blocked stale size updates while an active RW lease was held, not after the last writable handle closes. Add cifsInodeInfo->time_last_write, written via smp_store_release() at writable close and on setattr/truncate. is_size_safe_to_change() checks is_inode_writable() first (acquiring open_file_lock), then rejects a readdir size update if time_last_write falls within acregmax jiffies. The spinlock release in _cifsFileInfo_put() forms a store-release barrier that pairs with the spin_lock() (load-acquire) in is_inode_writable(), ensuring the subsequent smp_load_acquire() on time_last_write observes any update from a concurrent close(). When a size update is rejected and the server value differs from the cached one, cifs_i->time is cleared to force a fresh QUERY_INFO on the next stat(). readdir is also blocked from changing i_size while writable handles are open or an RW lease is held, even on direct-IO mounts. For deferred close (closetimeo > 0), time_last_write is refreshed at the actual server close in smb2_deferred_work_close() and in the cifs_close_deferred_file*() drain paths invoked by lease/oplock breaks and tcon teardown, anchoring the protection window to the real close time rather than the earlier userspace close. time_last_write == 0 skips the time_before() check to avoid false positives near boot on 32-bit systems where jiffies starts close to INITIAL_JIFFIES. Does not reproduce against Samba or with actimeo=0. Fixes: e4b61f3b1c67 ("cifs: prevent updating file size from server if we have a read/write lease") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-21smb: client: handle STATUS_STOPPED_ON_SYMLINK responses without a symlink targetCarl Johnson2-3/+41
The macOS built-in SMB server returns STATUS_STOPPED_ON_SYMLINK for a CREATE on a path whose final component is a symlink, but it does not include a Symbolic Link Error Response in the error data: both ErrorContextCount and ByteCount are zero, so the symlink target is not present in the response at all. Per [MS-SMB2] section 2.2.2 such a response should carry a valid Symbolic Link Error Response, so this is a server bug, but the target can still be retrieved with FSCTL_GET_REPARSE_POINT. Frame from a capture against macOS 26.5.2 (build 25F84): SMB2 hdr : Status=0x8000002d STATUS_STOPPED_ON_SYMLINK, Cmd=Create Error Rsp: StructureSize=0x0009 Error Context Count: 0 Byte Count: 0 Error Data: 00 symlink_data() cannot find a struct smb2_symlink_err_rsp in such a response and returns -EINVAL, which parse_create_response() propagates, so smb2_query_path_info() bails out at if (rc || !data->reparse_point) goto out; before it can retry with SMB2_OP_GET_REPARSE. stat(), readlink() and ls of any server-side symlink then fail with -EINVAL: $ ls -la Config l????????? ? ? ? ? ? Config.json $ stat Config/Config.json stat: cannot statx 'Config/Config.json': Invalid argument A 5.10 client resolves these symlinks correctly against the same server and share, so this is a regression for Apple SMB servers. Handle it in several places: - symlink_data() detects the empty response (ErrorContextCount and ByteCount both zero) and returns a distinct -ENODATA, so that "server did not send the target" can be told apart from a genuinely malformed response and only this case is worked around. - parse_create_response() treats -ENODATA like STATUS_IO_REPARSE_TAG_NOT_HANDLED, which does not carry the target either: leave the reparse tag unset and clear rc, so the existing SMB2_OP_GET_REPARSE path retrieves the target. - smb2_query_path_info() only fixes up the symlink target type when the target is already known. SMB2_OP_GET_REPARSE sets data->reparse.tag but does not parse the target out of the reparse buffer; that happens later, in reparse_info_to_fattr(). Without this check smb2_fix_symlink_target_type() is called with a NULL target and returns -EIO. This could not happen with servers that send the target inline and therefore skip SMB2_OP_GET_REPARSE. - smb2_open_file() maps -ENODATA to -EIO, matching STATUS_IO_REPARSE_TAG_NOT_HANDLED, so its callers retrieve the target with SMB2_OP_GET_REPARSE as well. Tested on Debian 13, kernel 6.18.38 (armv7), against macOS 26.5.2: symlinks now resolve, including relative, parent-traversing and directory symlinks, and reads through symlinks succeed. Cc: stable@vger.kernel.org Co-developed-by: Pali Rohár <pali@kernel.org> Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Carl Johnson <carl@jpartners.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-21fs: preserve ACL_DONT_CACHE state in forget_cached_acl()Amir Goldstein1-0/+7
The ACL_DONT_CACHE state is meant to be a constant state for the inode for filesystems that want to opt out of posix acl caching. Commit facd61053cff1 ("fuse: fixes after adapting to new posix acl api") used this facility to opt out of posix acl caching for fuse inodes with fuse server that does not negotiate FUSE_POSIX_ACL (fc->posix_acl). The commit also takes care to gate the forget_all_cached_acls() call in fuse_set_acl() on fc->posix_acl because there is no need for it, but there are other placed in fuse code which call forget_all_cached_acls() unconditional to fc->posix_acl and those cause the loss of the ACL_DONT_CACHE state. This is not only a functional bug. Properly timed, a get_acl() from this fuse filesystem can return a stale cached value, as was observed in tests, because set_acl() does not invalidate the unintentional acl cache. We could fix this in fuse, but it actually makes no sense for the vfs helper forget_cached_acl() to invalidate the ACL_DONT_CACHE state, so let it not do that to fix fuse and future users of ACL_DONT_CACHE. Fixes: facd61053cff1 ("fuse: fixes after adapting to new posix acl api") Cc: stable@vger.kernel.org Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://patch.msgid.link/20260713220932.413004-2-amir73il@gmail.com Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21Merge tag 'nfsd-7.2-2' of ↵Linus Torvalds1-1/+2
git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux Pull nfsd fix from Chuck Lever: - Fix issue with NLMv3 GRANTED_MSG introduced in v7.2 * tag 'nfsd-7.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: lockd: fix NLMv3 GRANTED_MSG handling
2026-07-21ext4: set EXT4_STATE_NO_EXPAND in ext4_evict_inodeYun Zhou1-0/+1
An inode being evicted will never need its extra isize expanded. Set EXT4_STATE_NO_EXPAND before ext4_mark_inode_dirty() in ext4_evict_inode() to make this explicit and prevent any unnecessary work in ext4_try_to_expand_extra_isize(). This also provides defense-in-depth for the s_writepages_rwsem deadlock during mount-time orphan cleanup, ensuring the expand path is blocked for inodes under eviction regardless of how they are reached. Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260623061903.2148767-2-yun.zhou@windriver.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: skip extra isize expansion during mount to prevent deadlockYun Zhou1-0/+10
ext4_try_to_expand_extra_isize() is called from __ext4_mark_inode_dirty() while holding an active jbd2 handle. During mount (!SB_ACTIVE), the expand path may move xattrs to external blocks and release ea_inodes via iput(). When !SB_ACTIVE, iput() calls write_inode_now() which acquires s_writepages_rwsem, creating a circular lock dependency: s_writepages_rwsem --> jbd2_handle --> xattr_sem --> s_writepages_rwsem This can be triggered via: ext4_process_orphan() -> ext4_truncate() -> ext4_mark_inode_dirty() -> ext4_try_to_expand_extra_isize() or: ext4_evict_inode() -> ext4_mark_inode_dirty() -> ext4_try_to_expand_extra_isize() Skip expansion when !SB_ACTIVE. This is a minor loss of functionality (extra isize won't grow for these inodes during mount), which e2fsck can resolve later if needed. Reported-by: syzbot+5d19358d7eb30ffb0cc5@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5d19358d7eb30ffb0cc5 Fixes: c8585c6fcaf2 ("ext4: fix races between changing inode journal mode and ext4_writepages") Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260623061903.2148767-1-yun.zhou@windriver.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: fix out-of-bounds read in ext4_read_inline_dir()Xiang Mei1-1/+10
ext4_read_inline_dir() can read a dirent header past the end of its inline buffer, triggering a slab-out-of-bounds read during getdents64(): BUG: KASAN: slab-out-of-bounds in __ext4_check_dir_entry Read of size 2 at addr ffff88800f3dd23c by task exploit/148 ... __ext4_check_dir_entry ext4_read_inline_dir iterate_dir The dirent payload lives in a buffer of exactly inline_size bytes: dir_buf = kmalloc(inline_size, GFP_NOFS); but iteration runs in a position space extra_offset bytes larger (extra_size = extra_offset + inline_size) so the synthetic "." and ".." land at their block-dir offsets. A dirent is formed at "dir_buf + pos - extra_offset", yet the ext4_check_dir_entry() length argument uses the larger extra_size. A position whose dirent header would extend past extra_size is therefore accepted, and the rescan loop's rec_len probe and ext4_check_dir_entry() dereference de->rec_len before the entry is rejected. Reject a position whose minimum-size dirent header would not fit within extra_size before forming de, in both the rescan and main loops, and pass inline_size rather than extra_size to ext4_check_dir_entry() so the length check matches the physical buffer. Fixes: c4d8b0235aa9 ("ext4: fix readdir error in case inline_data+^dir_index.") Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260615190519.946736-1-xmei5@asu.edu Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: remove ext4_end_buffer_io_sync()Matthew Wilcox (Oracle)1-20/+1
There's no need for a custom end_io routine here. We lose some tracing of I/O completions, but we gain better error handling. Well, consistent error handling anyway. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260615182527.2208479-1-willy@infradead.org Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: get ext4_group_desc in ext4_mb_prefetch only when necessaryBohdan Trach1-10/+11
Getting ext4_group_desc structure can contribute to the cost of ext4_mb_prefetch() without any need, as most groups fail the !EXT4_MB_GRP_TEST_AND_SET_READ check. Optimize ext4_mb_prefetch by getting the group description only when necessary. The result is further increase in performance of fallocate() system call path that triggers ext4_mb_prefetch() via a linear group scan. Signed-off-by: Bohdan Trach <bohdan.trach@huaweicloud.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Link: https://patch.msgid.link/20260615100331.163997-3-bohdan.trach@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: avoid RWM atomic in EXT4_MB_GRP_TEST_AND_SET_READBohdan Trach1-1/+7
EXT4_MB_GRP_TEST_AND_SET_READ uses test_and_set_bit function which issues an atomic write. This can cause high overhead due to cache contention when multiple threads iterate over groups in a tight loop, as is the case for ext4_mb_prefetch(). We have seen this to be a problem for Kunpeng 920b CPUs which uses a single ARM LSE instruction for this purpose. Avoid this unconditional atomic write by testing the bit first without changing its value. This is OK for this use case as this bit is never unset. This change significantly reduces costs of fallocate() operations which trigger linear group scans on large multicore machines where test_and_set_bit issues an atomic write operation unconditionally. Signed-off-by: Bohdan Trach <bohdan.trach@huaweicloud.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260615100331.163997-2-bohdan.trach@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: fix circular lock dependency in ext4_ext_migrateYun Zhou1-1/+2
Move iput(tmp_inode) after ext4_writepages_up_write() to avoid a circular lock dependency between s_writepages_rwsem and sb_internal (freeze protection). The deadlock scenario: CPU0 (EXT4_IOC_MIGRATE) CPU1 (orphan cleanup during mount) ---- ---- ext4_ext_migrate() ext4_writepages_down_write() s_writepages_rwsem (write) ext4_evict_inode() sb_start_intwrite() [sb_internal] ... ext4_writepages() s_writepages_rwsem (read) [BLOCKED] iput(tmp_inode) ext4_evict_inode() sb_start_intwrite() [BLOCKED] The tmp_inode is a temporary inode with nlink=0 created solely for building the extent tree. Its eviction does not require s_writepages_rwsem protection, so deferring iput() until after releasing the rwsem is safe. Reported-by: syzbot+212e8f62790f8e0bc63b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=212e8f62790f8e0bc63b Fixes: cb85f4d23f79 ("ext4: fix race between writepages and enabling EXT4_EXTENTS_FL") Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260612005330.1930804-1-yun.zhou@windriver.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: avoid tail write_begin walk for uptodate foliosJia Zhu1-5/+6
Ext4 buffered writes into large folios also pay a full buffer_head walk in ext4_block_write_begin(). For a small overwrite of an existing cached folio, the folio is already uptodate and the write only needs to prepare the buffers through the written range. Walking the suffix still makes the write_begin cost proportional to the folio size. Before ext4 enabled large folios for regular files, the same loop was bounded by a single page of buffers. That commit made the existing full-folio walk visible as a regression for cached small overwrites. The suffix walk is needed for non-uptodate folios, where ext4 may have to submit reads for partial blocks, preserve new-buffer cleanup, and run error zeroing. Keep those folios on the old full walk. For already-uptodate folios, keep the walk starting at the first buffer rather than seeking directly to from. This preserves the existing prefix buffer state handling. Stop once block_start reaches the end of the write range, because the skipped suffix would only repeat the outside-range uptodate handling for buffers beyond @to. On current master, the libMicro ext4 large-folio overwrite test shows the following full-series result. Results are median usecs/call over 10 runs, lower is better: case nofix this series improvement write_u1k 1.418 0.3405 76.0% write_u10k 1.887 0.4175 77.9% pwrite_u1k 1.6775 0.3390 79.8% pwrite_u10k 1.9035 0.4130 78.3% Fixes: 7ac67301e82f0 ("ext4: enable large folio for regular file") Cc: stable@vger.kernel.org # v6.16+ Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com> Link: https://patch.msgid.link/20260609035202.90669-3-zhujia.zj@bytedance.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21buffer: avoid tail commit walk for uptodate foliosJia Zhu1-0/+3
block_commit_write() always walks every buffer_head attached to the folio. That was cheap for order-0 folios, but large folios can contain hundreds of buffer_heads. For a small buffered overwrite of an already-uptodate large folio, the commit work is therefore proportional to the folio size rather than the copied range. This became visible with ext4 regular-file large folios, where cached small overwrites reach block_commit_write() through block_write_end(). Before ext4 enabled large folios for regular files, this path was only hit with order-0 folios for normal ext4 buffered writes, so the full walk was bounded. The ext4 large-folio commit is therefore the regression point for this generic helper cost. The full walk is still needed when the folio is not uptodate, because block_commit_write() uses per-buffer uptodate state to decide whether the whole folio can be marked uptodate. Keep those folios on the old full-buffer path. For a folio that was already uptodate on entry, the commit no longer needs tail buffers for folio-uptodate discovery. The copied range has already been processed once block_start reaches @to, so stop there and avoid the suffix walk. Fixes: 7ac67301e82f0 ("ext4: enable large folio for regular file") Suggested-by: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: stable@vger.kernel.org # v6.16+ Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com> Link: https://patch.msgid.link/20260609035202.90669-2-zhujia.zj@bytedance.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: reject mount if inodes per group is not a multiple of inodes per blockBaokun Li1-1/+2
If s_inodes_per_group is not a multiple of s_inodes_per_block, the division that computes s_itb_per_group truncates, reserving fewer blocks for the inode table than needed. On a crafted filesystem image, this allows __ext4_get_inode_loc() to compute a block offset beyond the inode table, reading unrelated data as an inode structure. Add the missing divisibility check alongside the existing validation in ext4_block_group_meta_init(). Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260608061112.392391-1-libaokun%40linux.alibaba.com Signed-off-by: Baokun Li <libaokun@linux.alibaba.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Link: https://patch.msgid.link/20260608111150.827117-4-libaokun@linux.alibaba.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: reduce max cluster size to match documented 256MB limitBaokun Li1-1/+1
The mke2fs man page documents: Valid cluster-size values are from 2048 to 256M bytes per cluster. but EXT4_MAX_CLUSTER_LOG_SIZE was set to 30 (1GB), allowing crafted filesystem images to specify cluster sizes up to 1GB. On 32-bit systems with bigalloc enabled, the consistency check in ext4_handle_clustersize(): s_blocks_per_group == s_clusters_per_group * (clustersize / blocksize) can overflow when the cluster ratio is large enough. Since s_blocks_per_group is not range-checked in the bigalloc path, the wrapped product can pass the consistency check, leading to inconsistent group geometry and potential out-of-bounds block allocation. Reduce EXT4_MAX_CLUSTER_LOG_SIZE to 28 to match the documented 256MB limit. With this cap, the maximum product is: (blocksize * 8) * (256M / blocksize) = 2^31 which fits safely in a 32-bit unsigned long for all block sizes. Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260608061112.392391-1-libaokun%40linux.alibaba.com Signed-off-by: Baokun Li <libaokun@linux.alibaba.com> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Link: https://patch.msgid.link/20260608111150.827117-3-libaokun@linux.alibaba.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21ext4: reject mount if clusters/inodes per group are not 8-alignedBaokun Li1-4/+6
The block and inode bitmap checksums are computed over a whole number of bytes: ext4_inode_bitmap_csum_*() use EXT4_INODES_PER_GROUP(sb) >> 3 and ext4_block_bitmap_csum_*() use EXT4_CLUSTERS_PER_GROUP(sb) / 8 as the length passed to ext4_chksum(). If s_inodes_per_group or s_clusters_per_group is not a multiple of 8, the trailing fractional bits are excluded from the checksum. Those bits are then unprotected, and any incremental csum update path that assumes a byte-aligned bitmap can compute a checksum inconsistent with the full recalculation, corrupting the on-disk bitmap checksum. Reject such filesystems at mount time by adding the missing " & 7" alignment checks alongside the existing range validation. Suggested-by: Theodore Ts'o <tytso@mit.edu> Link: https://patch.msgid.link/h3n7jlfhyna64dn5o76qxcspnhxdddcs6crpxftmy7gnl7b3sx@jenszfpcsnit Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260508121539.4174601-1-libaokun%40linux.alibaba.com?part=10 Signed-off-by: Baokun Li <libaokun@linux.alibaba.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20260608111150.827117-2-libaokun@linux.alibaba.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-21Merge tag 'for-7.2-rc4-tag' of ↵Linus Torvalds8-21/+79
git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "I'm catching up with the fix backlog in the development branch, so here's a number of them and will probably send one more for this or the next rc: - relocation fixes: - skip attempting compression on reloc inodes - exclude inline extents from file extent offset checks - fix minor memory leak after error when adding reloc root - fix root cleanup after inserting and merging - fix clearing folio tags after writeback - clear logging flag of extent map before splitting - fix unsigned 32/64 type conversions when accounting dirty metadata, leading to continually exceeding threshold - fix regression in 32bit compat ioctl for subvolume info - fix type of SEARCH_TREE ioctl buffer in UAPI header - fix expression in ASSERT expression which can be unconditionally evaluated on some compilers - only account delalloc bytes for regular inodes" * tag 'for-7.2-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix GET_SUBVOL_INFO after compat refactor btrfs: free mapping node on duplicate reloc root insert btrfs: fix a regression where PAGECACHE_TAG_DIRTY is never cleared btrfs: don't propagate EXTENT_FLAG_LOGGING to split extent maps btrfs: fix u32 to s64 type conversion in dirty_metadata_bytes accounting btrfs: fix NULL pointer deref during assertion in btrfs_backref_free_node() btrfs: only account delalloc bytes for regular file inodes in btrfs_getattr() btrfs: reject inline file extents item in get_new_location() btrfs: do not try compression for data reloc inodes btrfs: declare btrfs_ioctl_search_args_v2::buf as __u8 btrfs: fix reloc root cleanup in merge_reloc_roots() btrfs: fix use-after-free on reloc root after error in insert_dirty_subvol()
2026-07-21binfmt_elf_fdpic: only honour the first PT_INTERPChristian Brauner1-0/+4
The program header scan handles PT_INTERP from a switch nested in the scan loop, so its break leaves the switch and not the loop. A binary carrying more than one PT_INTERP runs the case again and overwrites both interpreter_name and interpreter. The previous name allocation leaks and so does the previous interpreter reference, along with the write denial open_exec() took on it. The denial is never released, so the file stays unwritable for as long as the system runs. An unprivileged caller reaches this with a crafted binary and repeats it at will. binfmt_elf stops at the first PT_INTERP. Do the same here. The flaw dates back to the driver's introduction in the pre-git history tree introduced in v2.6.11 by 91808d6ebe39 ("[PATCH] FRV: Add FDPIC ELF binary format driver"). Link: https://patch.msgid.link/20260721-gezittert-medium-kreide-b41fc1f0277e@brauner Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21exec: fix unsigned loop counter wrap in transfer_args_to_stack()Christian Brauner1-1/+1
The stop value is derived from bprm->p >> PAGE_SHIFT. The index variable is an unsigned long. If bprm->p drops below PAGE_SIZE and stop becomes zero the loop condition index >= stop is always true. After the index == 0 iteration the decrement wraps to ULONG_MAX and bprm->page[ULONG_MAX] reads sizeof(void *) bytes in front of the array. The pointer has wrapped to -1. That garbage pointer is then passed to kmap_local_page() and PAGE_SIZE bytes are copied from wherever that lands into the stack of the process being created. And the loop doesn't terminate either... Getting there only requires bprm->p < PAGE_SIZE. On !MMU bprm_set_stack_limit() and bprm_hit_stack_limit() are empty. So the only constraint on how far bprm->p is pushed down is valid_arg_len(), i.e. that each individual string still fits in what is left. bprm->p starts at PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *) so a single argument or environment string of a little over 31 pages leaves it in the first page: Oops - load access fault [#1] CPU: 0 UID: 0 PID: 1 Comm: victim Not tainted 7.2.0-rc4 #1 epc : __memcpy+0xd4/0xf8 ra : transfer_args_to_stack+0xaa/0xae s4 : ffffffffffffffff s2 : 0000000000000000 a1 : ffffffdc98000000 a2 : 0000000000001000 status: 0000000a00001880 badaddr: ffffffdc98000000 cause: 0000000000000005 [<801a5324>] __memcpy+0xd4/0xf8 [<800d5f6a>] load_flat_binary+0x43a/0x65e [<800a2de4>] bprm_execve+0x1d4/0x316 [<800a351a>] do_execveat_common+0x12e/0x138 [<800a3d44>] __riscv_sys_execve+0x38/0x4e Kernel panic - not syncing: Fatal exception in interrupt This is an arcane bug but we should still fix it. Count down from MAX_ARG_PAGES so the loop ends when index reaches stop, stop == 0 included. The iterations performed are unchanged for every other value of stop. Only CONFIG_MMU=n builds are affected, transfer_args_to_stack() is used by binfmt_flat and binfmt_elf_fdpic on nommu only. The loop predates git history. commit 7e7ec6a93434 ("elf_fdpic_transfer_args_to_stack(): make it generic") only moved it from binfmt_elf_fdpic.c into fs/exec.c and narrowed the copy to the used part of the first page. The condition and the decrement are unchanged from 2.6.12-rc2. Link: https://patch.msgid.link/20260721-hochachtung-staumauer-pigmente-15d71f7d7d04@brauner Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21ntfs: drop stale page-cache when shrinking a non-resident attrNamjae Jeon1-0/+10
ntfs_non_resident_attr_shrink() shrinks attribute sizes but fails to trim the page cache. This leaves orphaned dirty folios beyond the new end of the attribute, leading to writeback failures (-ENOENT), data loss, and $EA chain corruption. Fix this by truncating the page cache to the new size immediately after updating the sizes, preventing writeback from flushing out-of-range folios. Fixes: 495e90fa3348 ("ntfs: update attrib operations") Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-07-21ntfs: harden runlist realloc size calculationsNamjae Jeon1-23/+27
Add a shared helper to safely convert runlist element counts to byte sizes using overflow checks, and use it in both ntfs_rl_realloc() and ntfs_rl_realloc_nofail(). Fixes: 11ccc9107dc4 ("ntfs: update runlist handling and cluster allocator") Co-developed-by: Alper Mudar <kommandant_alper@proton.me> Signed-off-by: Alper Mudar <kommandant_alper@proton.me> Tested-by: Alper Mudar <kommandant_alper@proton.me> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-07-21btrfs: raid56: fix scrub read assembly submitting no readsMykola Lysenko1-6/+5
Commit 5387bd958180 ("btrfs: raid56: remove sector_ptr structure") converted the bio-list membership checks from sector pointers to physical addresses. The two conversions in rmw_assemble_write_bios() kept their polarity (skip the sector when it is NOT in the bio list, i.e. when there is nothing to write), but scrub_assemble_read_bios() has the opposite polarity -- skip the sector when it IS in the bio list, because then there is nothing to read -- and the conversion flipped it: - sector = sector_in_rbio(rbio, stripe, sectornr, 1); - if (sector) + paddr = sector_paddr_in_rbio(rbio, stripe, sectornr, 1); + if (paddr == INVALID_PADDR) continue; Since a parity-scrub rbio's bio list only holds the empty completion bio, the result is that scrub_assemble_read_bios() submits no reads at all. finish_parity_scrub() then compares the parity it computes from the (cached, correct) data stripes against whatever happens to be in the freshly allocated, uninitialized stripe pages: - if the garbage differs from the computed parity, the sector is "repaired" and written back -- accidentally producing the correct on-disk result; - if a recycled page happens to still hold the old (correct) parity content, the sector is deemed clean, dropped from dbitmap, and the actually-corrupt on-disk parity is left in place. (Scrub reports no errors either way: there is no counter for P/Q corruption by design, so the bug here is purely the failure to read and repair.) The second case is intermittent because it depends on page-allocator recycling. Observed with fstests btrfs/297 (raid5, 2 devices): the corrupted P stripe intermittently stays corrupt after a scrub -- roughly 1/10 runs on x86-64 KVM and up to 7/8 on a UML build whose timing favors page reuse. Since the bio-list check can never be true for a parity-scrub rbio -- raid56_parity_alloc_scrub_rbio() adds a single empty completion bio (asserting bi_size == 0), bio_paddrs[] is only populated by index_rbio_pages() which is never called for BTRFS_RBIO_PARITY_SCRUB, and rbio_can_merge() refuses to merge rbios of different operations -- remove the dead check entirely and assert the invariant instead, as suggested by Qu Wenruo. After this fix the injected corruption is read, detected and repaired in every run (8/8 UML, 10/10 KVM), and the new assertion never fires across the full fstests raid group. Fixes: 5387bd958180 ("btrfs: raid56: remove sector_ptr structure") CC: stable@vger.kernel.org # 7.1+ Suggested-by: Qu Wenruo <quwenruo.btrfs@gmx.com> Assisted-by: Claude:claude-fable-5 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Mykola Lysenko <nickolay.lysenko@gmail.com> Signed-off-by: David Sterba <dsterba@suse.com>