From: Linus Torvalds Date: Wed, 24 Jun 2026 17:05:53 +0000 (-0700) Subject: Merge tag 'ntfs3_for_7.2' of https://github.com/Paragon-Software-Group/linux-ntfs3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0e6f20cb52b14c2c441f04e21cef0c95d498cac;p=thirdparty%2Flinux.git Merge tag 'ntfs3_for_7.2' of https://github.com/Paragon-Software-Group/linux-ntfs3 Pull ntfs3 updates from Konstantin Komarov: "Added: - depth limit to indx_find_buffer() to prevent stack overflow - validate split-point offset in indx_insert_into_buffer() - bounds check to run_get_highest_vcn() - fileattr_get() and fileattr_set() support - zero stale pagecache beyond valid data length - handle delayed allocation overlap in run lookup - validate lcns_follow in log_replay() conversion - cap RESTART_TABLE free-chain walker at rt->used - resize log->one_page_buf when adopting on-disk page size - reject direct userspace writes to reserved $LX* xattrs Fixed: - out-of-bounds read in decompress_lznt() - avoid -Wmaybe-uninitialized warnings - hold ni_lock across readdir metadata walk - preserve non-DOS attribute bits in system.dos_attrib - validate index entry key bounds - syncing wrong inode on DIRSYNC cross-directory rename - validate Dirty Page Table capacity in log_replay() copy_lcns - wrong LCN in run_remove_range() when splitting a run - allocate iomap inline_data using alloc_page - mount failure on 64K page-size kernels - out-of-bounds read in ntfs_dir_emit() and hdr_find_e() - bound attr_off in UpdateResidentValue against data_off - bound DeleteIndexEntryAllocation memmove length - bound copy_lcns dp->page_lcns[] index in analysis pass - bound NTFS_DE view.data_off in UpdateRecordData{Root,Allocation} - prevent potential lcn remains uninitialized Changed: - bound to_move in indx_insert_into_root() before hdr_insert_head() - call _ntfs_bad_inode() when failing to rename - fold resident writeback into writepages loop - force waiting for direct I/O completion - fold file size handling into ntfs_set_size() - reject SEEK_DATA and SEEK_HOLE past EOF early - format code, add descriptive comments and remove non-useful" * tag 'ntfs3_for_7.2' of https://github.com/Paragon-Software-Group/linux-ntfs3: (34 commits) ntfs3: reject direct userspace writes to reserved $LX* xattrs fs/ntfs3: resize log->one_page_buf when adopting on-disk page size fs/ntfs3: prevent potential lcn remains uninitialized ntfs3: cap RESTART_TABLE free-chain walker at rt->used fs/ntfs3: bound NTFS_DE view.data_off in UpdateRecordData{Root,Allocation} fs/ntfs3: validate lcns_follow in log_replay conversion fs/ntfs3: bound copy_lcns dp->page_lcns[] index in analysis pass fs/ntfs3: bound DeleteIndexEntryAllocation memmove length fs/ntfs3: bound attr_off in UpdateResidentValue against data_off ntfs3: fix out-of-bounds read in ntfs_dir_emit() and hdr_find_e() fs/ntfs3: fix mount failure on 64K page-size kernels ntfs3: avoid another -Wmaybe-uninitialized warning ntfs3: Allocate iomap inline_data using alloc_page fs/ntfs3: format code, deal with comments fs/ntfs3: reject SEEK_DATA and SEEK_HOLE past EOF early fs/ntfs3: fold file size handling into ntfs_set_size() fs/ntfs3: force waiting for direct I/O completion fs/ntfs3: fold resident writeback into writepages loop fs/ntfs3: handle delayed allocation overlap in run lookup fs/ntfs3: zero stale pagecache beyond valid data length ... --- f0e6f20cb52b14c2c441f04e21cef0c95d498cac diff --cc fs/ntfs3/file.c index ad9350d7fc3fd,1b52447bd2289..d601f088618c0 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@@ -89,6 -89,80 +89,84 @@@ static int ntfs_ioctl_fitrim(struct ntf return 0; } + /* + * ntfs_fileattr_get - inode_operations::fileattr_get + */ + int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa) + { + struct inode *inode = d_inode(dentry); ++ struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info; + struct ntfs_inode *ni = ntfs_i(inode); + u32 flags = 0; + + /* Avoid any operation if inode is bad. */ + if (unlikely(is_bad_ni(ni))) + return -EINVAL; + ++ if (sbi->options->nocase) ++ flags |= FS_CASEFOLD_FL; ++ + if (inode->i_flags & S_IMMUTABLE) + flags |= FS_IMMUTABLE_FL; + + if (inode->i_flags & S_APPEND) + flags |= FS_APPEND_FL; + + if (is_compressed(ni)) + flags |= FS_COMPR_FL; + + if (is_encrypted(ni)) + flags |= FS_ENCRYPT_FL; + + if (ni->nodump) + flags |= FS_NODUMP_FL; + + fileattr_fill_flags(fa, flags); + + return 0; + } + + /* + * ntfs_fileattr_set - inode_operations::fileattr_set + */ + int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, + struct file_kattr *fa) + { + struct inode *inode = d_inode(dentry); + struct ntfs_inode *ni = ntfs_i(inode); + u32 flags = fa->flags; + unsigned int new_fl = 0; + + /* Avoid any operation if inode is bad. */ + if (unlikely(is_bad_ni(ni))) + return -EINVAL; + + if (fileattr_has_fsx(fa)) + return -EOPNOTSUPP; + + if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL)) + return -EOPNOTSUPP; + + if (flags & FS_IMMUTABLE_FL) + new_fl |= S_IMMUTABLE; + + if (flags & FS_APPEND_FL) + new_fl |= S_APPEND; + + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); + + /* Save nodump flag to return in ntfs_getattr. */ + if (flags & FS_NODUMP_FL) + ni->nodump = 1; + else + ni->nodump = 0; + + inode_set_ctime_current(inode); + mark_inode_dirty(inode); + + return 0; + } + static int ntfs_ioctl_get_volume_label(struct ntfs_sb_info *sbi, u8 __user *buf) { if (copy_to_user(buf, sbi->volume.label, FSLABEL_MAX))