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-01 19:27:52
Also in: linux-fsdevel, linux-xfs, lkml, selinux

On Tue, Jul 1, 2025 at 8:31 PM Darrick J. Wong [off-list ref] wrote:
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.
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.
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.

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