Commit e9734653 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Eric Biggers
Browse files

fs,fsverity: reject size changes on fsverity files in setattr_prepare



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: 14605409 ("btrfs: initial fsverity support")
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatar"Darrick J. Wong" <djwong@kernel.org>
Link: https://lore.kernel.org/r/20260128152630.627409-2-hch@lst.de


Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
parent 63804fed
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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;
	}
+0 −4
Original line number Diff line number Diff line
@@ -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)
+0 −4
Original line number Diff line number Diff line
@@ -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;

+0 −8
Original line number Diff line number Diff line
@@ -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);
+0 −25
Original line number Diff line number Diff line
@@ -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 */