]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fs,fsverity: reject size changes on fsverity files in setattr_prepare
authorChristoph Hellwig <hch@lst.de>
Wed, 28 Jan 2026 15:26:13 +0000 (16:26 +0100)
committerEric Biggers <ebiggers@kernel.org>
Thu, 29 Jan 2026 17:39:41 +0000 (09:39 -0800)
Add the check to reject truncates of fsverity files directly to
setattr_prepare instead of requiring the file system to handle it.
Besides removing boilerplate code, this also fixes the complete lack of
such check in btrfs.

Fixes: 146054090b08 ("btrfs: initial fsverity support")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Link: https://lore.kernel.org/r/20260128152630.627409-2-hch@lst.de
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
fs/attr.c
fs/ext4/inode.c
fs/f2fs/file.c
fs/verity/open.c
include/linux/fsverity.h

index b9ec6b47bab2fc2b561677b639633bd32994022f..e7d7c6d19fe9036d83248fd789a0f8876f339f9a 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -169,7 +169,17 @@ int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,
         * ATTR_FORCE.
         */
        if (ia_valid & ATTR_SIZE) {
-               int error = inode_newsize_ok(inode, attr->ia_size);
+               int error;
+
+               /*
+                * Verity files are immutable, so deny truncates.  This isn't
+                * covered by the open-time check because sys_truncate() takes a
+                * path, not an open file.
+                */
+               if (IS_ENABLED(CONFIG_FS_VERITY) && IS_VERITY(inode))
+                       return -EPERM;
+
+               error = inode_newsize_ok(inode, attr->ia_size);
                if (error)
                        return error;
        }
index 0c466ccbed69672a983339fa53d0bdc986f7d885..8c2ef98fa53042b8e42ccea3c35ee5898c7fda96 100644 (file)
@@ -5835,10 +5835,6 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
        if (error)
                return error;
 
-       error = fsverity_prepare_setattr(dentry, attr);
-       if (error)
-               return error;
-
        if (is_quota_modification(idmap, inode, attr)) {
                error = dquot_initialize(inode);
                if (error)
index d7047ca6b98d8a41d69ea79bcbab3e4ae4cf30b6..da029fed4e5af28e1130123b8a82833a9b4b842f 100644 (file)
@@ -1074,10 +1074,6 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
        if (err)
                return err;
 
-       err = fsverity_prepare_setattr(dentry, attr);
-       if (err)
-               return err;
-
        if (unlikely(IS_IMMUTABLE(inode)))
                return -EPERM;
 
index 77b1c977af025693024bd619d7e6ed9bcdecd374..2aa5eae5a54039e890cffd56c7615a60f702ba32 100644 (file)
@@ -384,14 +384,6 @@ int __fsverity_file_open(struct inode *inode, struct file *filp)
 }
 EXPORT_SYMBOL_GPL(__fsverity_file_open);
 
-int __fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
-{
-       if (attr->ia_valid & ATTR_SIZE)
-               return -EPERM;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(__fsverity_prepare_setattr);
-
 void __fsverity_cleanup_inode(struct inode *inode)
 {
        struct fsverity_info **vi_addr = fsverity_info_addr(inode);
index 5bc7280425a719a61e32ed32613ae3cb882ae337..86fb1708676bac9482308ab6337ae05cc286dfad 100644 (file)
@@ -179,7 +179,6 @@ int fsverity_get_digest(struct inode *inode,
 /* open.c */
 
 int __fsverity_file_open(struct inode *inode, struct file *filp);
-int __fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr);
 void __fsverity_cleanup_inode(struct inode *inode);
 
 /**
@@ -251,12 +250,6 @@ static inline int __fsverity_file_open(struct inode *inode, struct file *filp)
        return -EOPNOTSUPP;
 }
 
-static inline int __fsverity_prepare_setattr(struct dentry *dentry,
-                                            struct iattr *attr)
-{
-       return -EOPNOTSUPP;
-}
-
 static inline void fsverity_cleanup_inode(struct inode *inode)
 {
 }
@@ -338,22 +331,4 @@ static inline int fsverity_file_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-/**
- * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
- * @dentry: dentry through which the inode is being changed
- * @attr: attributes to change
- *
- * Verity files are immutable, so deny truncates.  This isn't covered by the
- * open-time check because sys_truncate() takes a path, not a file descriptor.
- *
- * Return: 0 on success, -errno on failure
- */
-static inline int fsverity_prepare_setattr(struct dentry *dentry,
-                                          struct iattr *attr)
-{
-       if (IS_VERITY(d_inode(dentry)))
-               return __fsverity_prepare_setattr(dentry, attr);
-       return 0;
-}
-
 #endif /* _LINUX_FSVERITY_H */