Re: [RFC PATCH 1/2] fs: prepare for extending [gs]etfsxattrat()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2025-03-29 15:33:11, Amir Goldstein wrote:
> We intend to add support for more xflags to selective filesystems and
> We cannot rely on copy_struct_from_user() to detect this extention.
> 
> In preparation of extending the API, do not allow setting xflags unknown
> by this kernel version.
> 
> Also do not pass the read-only flags and read-only field fsx_nextents to
> filesystem.
> 
> These changes should not affect existing chattr programs that use the
> ioctl to get fsxattr before setting the new values.
> 
> Link: https://lore.kernel.org/linux-fsdevel/20250216164029.20673-4-pali@xxxxxxxxxx/
> Cc: Pali Rohár <pali@xxxxxxxxxx>
> Cc: Andrey Albershteyn <aalbersh@xxxxxxxxxx>
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---
>  fs/inode.c               |  4 +++-
>  fs/ioctl.c               | 19 +++++++++++++------
>  include/linux/fileattr.h | 22 +++++++++++++++++++++-
>  3 files changed, 37 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index 3cfcb1b9865ea..6c4d08bd53052 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -3049,7 +3049,9 @@ SYSCALL_DEFINE5(setfsxattrat, int, dfd, const char __user *, filename,
>  	if (error)
>  		return error;
>  
> -	fsxattr_to_fileattr(&fsx, &fa);
> +	error = fsxattr_to_fileattr(&fsx, &fa);
> +	if (error)
> +		return error;
>  
>  	name = getname_maybe_null(filename, at_flags);
>  	if (!name) {
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 840283d8c4066..b19858db4c432 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -540,8 +540,10 @@ EXPORT_SYMBOL(vfs_fileattr_get);
>  
>  void fileattr_to_fsxattr(const struct fileattr *fa, struct fsxattr *fsx)
>  {
> +	__u32 mask = FS_XFALGS_MASK;
> +
>  	memset(fsx, 0, sizeof(struct fsxattr));
> -	fsx->fsx_xflags = fa->fsx_xflags;
> +	fsx->fsx_xflags = fa->fsx_xflags & mask;
>  	fsx->fsx_extsize = fa->fsx_extsize;
>  	fsx->fsx_nextents = fa->fsx_nextents;
>  	fsx->fsx_projid = fa->fsx_projid;
> @@ -568,13 +570,20 @@ int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
>  }
>  EXPORT_SYMBOL(copy_fsxattr_to_user);
>  
> -void fsxattr_to_fileattr(const struct fsxattr *fsx, struct fileattr *fa)
> +int fsxattr_to_fileattr(const struct fsxattr *fsx, struct fileattr *fa)
>  {
> +	__u32 mask = FS_XFALGS_MASK;
> +
> +	if (fsx->fsx_xflags & ~mask)
> +		return -EINVAL;
> +
>  	fileattr_fill_xflags(fa, fsx->fsx_xflags);
> +	fa->fsx_xflags &= ~FS_XFLAG_RDONLY_MASK;
>  	fa->fsx_extsize = fsx->fsx_extsize;
> -	fa->fsx_nextents = fsx->fsx_nextents;
>  	fa->fsx_projid = fsx->fsx_projid;
>  	fa->fsx_cowextsize = fsx->fsx_cowextsize;
> +
> +	return 0;
>  }
>  
>  static int copy_fsxattr_from_user(struct fileattr *fa,
> @@ -585,9 +594,7 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
>  	if (copy_from_user(&xfa, ufa, sizeof(xfa)))
>  		return -EFAULT;
>  
> -	fsxattr_to_fileattr(&xfa, fa);
> -
> -	return 0;
> +	return fsxattr_to_fileattr(&xfa, fa);
>  }
>  
>  /*
> diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
> index 31888fa2edf10..f682bfc7749dd 100644
> --- a/include/linux/fileattr.h
> +++ b/include/linux/fileattr.h
> @@ -14,6 +14,26 @@
>  	 FS_XFLAG_NODUMP | FS_XFLAG_NOATIME | FS_XFLAG_DAX | \
>  	 FS_XFLAG_PROJINHERIT)
>  
> +/* Read-only inode flags */

Maybe it's only me, but this "read-only" is a bit confusing, as
those are not settable get-only flags and not flags of read-only
inode

> +#define FS_XFLAG_RDONLY_MASK \
> +	(FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR)
> +
> +/* Flags to indicate valid value of fsx_ fields */
> +#define FS_XFLAG_VALUES_MASK \
> +	(FS_XFLAG_EXTSIZE | FS_XFLAG_COWEXTSIZE)
> +
> +/* Flags for directories */
> +#define FS_XFLAG_DIRONLY_MASK \
> +	(FS_XFLAG_RTINHERIT | FS_XFLAG_NOSYMLINKS | FS_XFLAG_EXTSZINHERIT)
> +
> +/* Misc settable flags */
> +#define FS_XFLAG_MISC_MASK \
> +	(FS_XFLAG_REALTIME | FS_XFLAG_NODEFRAG | FS_XFLAG_FILESTREAM)
> +
> +#define FS_XFALGS_MASK \
> +	(FS_XFLAG_COMMON | FS_XFLAG_RDONLY_MASK | FS_XFLAG_VALUES_MASK | \
> +	 FS_XFLAG_DIRONLY_MASK | FS_XFLAG_MISC_MASK)
> +

I like the splitting but do we want to split flags like this? I can
imagine new flags just getting pushed into _MISK_MASK or these names
just loosing any sense.

>  /*
>   * Merged interface for miscellaneous file attributes.  'flags' originates from
>   * ext* and 'fsx_flags' from xfs.  There's some overlap between the two, which
> @@ -35,7 +55,7 @@ struct fileattr {
>  
>  void fileattr_to_fsxattr(const struct fileattr *fa, struct fsxattr *fsx);
>  int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa);
> -void fsxattr_to_fileattr(const struct fsxattr *fsx, struct fileattr *fa);
> +int fsxattr_to_fileattr(const struct fsxattr *fsx, struct fileattr *fa);
>  
>  void fileattr_fill_xflags(struct fileattr *fa, u32 xflags);
>  void fileattr_fill_flags(struct fileattr *fa, u32 flags);
> -- 
> 2.34.1
> 

Otherwise, this patch looks fine for limiting the interface for now

I will include it in next iteration

-- 
- Andrey





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux