Thread (52 messages) 52 messages, 8 authors, 2025-10-07

Re: [PATCH v6 5/6] fs: prepare for extending file_get/setattr()

From: Amir Goldstein <amir73il@gmail.com>
Date: 2025-07-02 09:48:53
Also in: linux-fsdevel, linux-xfs, lkml, selinux

On Wed, Jul 2, 2025 at 9:03 AM Amir Goldstein [off-list ref] wrote:
On Tue, Jul 1, 2025 at 9:54 PM Pali Rohár [off-list ref] wrote:
quoted
On Tuesday 01 July 2025 12:40:02 Darrick J. Wong wrote:
quoted
On Tue, Jul 01, 2025 at 09:27:38PM +0200, Amir Goldstein wrote:
quoted
On Tue, Jul 1, 2025 at 8:31 PM Darrick J. Wong [off-list ref] wrote:
quoted
On Mon, Jun 30, 2025 at 06:20:15PM +0200, Andrey Albershteyn wrote:
quoted
From: Amir Goldstein <amir73il@gmail.com>

We intend to add support for more xflags to selective filesystems and
We cannot rely on copy_struct_from_user() to detect this extension.

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@kernel.org/ (local)
Cc: Pali Rohár <pali@kernel.org>
Cc: Andrey Albershteyn <redacted>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
 fs/file_attr.c           |  8 +++++++-
 include/linux/fileattr.h | 20 ++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/fs/file_attr.c b/fs/file_attr.c
index 4e85fa00c092..62f08872d4ad 100644
--- a/fs/file_attr.c
+++ b/fs/file_attr.c
@@ -99,9 +99,10 @@ EXPORT_SYMBOL(vfs_fileattr_get);
 int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
 {
      struct fsxattr xfa;
+     __u32 mask = FS_XFLAGS_MASK;

      memset(&xfa, 0, sizeof(xfa));
-     xfa.fsx_xflags = fa->fsx_xflags;
+     xfa.fsx_xflags = fa->fsx_xflags & mask;
I wonder, should it be an error if a filesystem sets an fsx_xflags bit
outside of FS_XFLAGS_MASK?  I guess that's one way to prevent
filesystems from overriding the VFS bits. ;)
I think Pali has a plan on how to ensure that later
when the mask is provided via the API.
quoted
Though couldn't that be:

        xfa.fsx_xflags = fa->fsx_xflags & FS_XFLAGS_MASK;

instead?  And same below?
Indeed. There is a reason for the var, because the next series
by Pali will use a user provided mask, which defaults to FS_XFLAGS_MASK,
so I left it this way.

I don't see a problem with it keeping as is, but if it bothers you
I guess we can re-add the var later.
Nah, it doesn't bother me that much.
quoted
quoted
quoted
      xfa.fsx_extsize = fa->fsx_extsize;
      xfa.fsx_nextents = fa->fsx_nextents;
      xfa.fsx_projid = fa->fsx_projid;
@@ -118,11 +119,16 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
                                struct fsxattr __user *ufa)
 {
      struct fsxattr xfa;
+     __u32 mask = FS_XFLAGS_MASK;

      if (copy_from_user(&xfa, ufa, sizeof(xfa)))
              return -EFAULT;

+     if (xfa.fsx_xflags & ~mask)
+             return -EINVAL;
I wonder if you want EOPNOTSUPP here?  We don't know how to support
unknown xflags.  OTOH if you all have beaten this to death while I was
out then don't start another round just for me. :P
We have beaten this API almost to death for sure ;)
I don't remember if we discussed this specific aspect,
but I am personally in favor of
EOPNOTSUPP := the fs does not support the set/get operation
EINVAL := some flags provided as value is invalid

For example, if the get API provides you with a mask of the
valid flags that you can set, if you try to set flags outside of
that mask you get EINVAL.

That's my interpretation, but I agree that EOPNOTSUPP can also
make sense in this situation.
<nod> I think I'd rather EOPNOTSUPP for "bits are set that the kernel
doesn't recognize" and EINVAL (or maybe something else like
EPROTONOSUPPORT) for "fs driver will not let you change this bit".
At least for the syscall interface; we probably have to flatten that to
EOPNOTSUPP for both legacy ioctls.
Given the precedents of returning EOPNOTSUPP in xfs_fileattr_set()
and ext4_ioctl_setflags() for flags that cannot be set, I agree.
Wait, I misparsed what you wrote, so I think I "agreed" only to the
first part of your suggestion.

My claim is that unlike the xfs_has_v3inodes() check in
xfs_ioctl_setattr_xflags(),
ext4/f2fs etc return EOPNOTSUPP for various flags depending on supported fs
features (e.g. casefold,dax,encryption), so I think it will be hard to
impose a strict rule
where "fs does not support the feature" returns EINVAL in the syscalls API.

Therefore, I propose to change the code in this patch to
return EOPNOTSUPP for flags that kernel does not support
and with coming changes from Pali, it will also return the same
EOPNOTSUPP for flags that the fs instance does not support.

Christian,

Can you please amend the return value in the following chunk:
@@ -119,11 +120,16 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
                                  struct fsxattr __user *ufa)
 {
        struct fsxattr xfa;
+       __u32 mask = FS_XFLAGS_MASK;

        if (copy_from_user(&xfa, ufa, sizeof(xfa)))
                return -EFAULT;

+       if (xfa.fsx_xflags & ~mask)
+               return -EOPNOTSUPP;
+
Thanks,
Amir.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help