2022-02-01 11:15:39

by Harry Austen

[permalink] [raw]
Subject: [RFC PATCH] f2fs: disallow setting unsettable file attributes

After Eric kindly pointed out the reasons why my initial kernel patch
attempt was incorrect
(https://lore.kernel.org/lkml/[email protected]/), I had a
rethink as to if the current implementation could be improved in any
way.

I wondered whether something along the lines of the following patch
would be more acceptable? It is intentionally verbose in order to
demonstrate the concept as this is intended purely as an RFC.

What if SETFLAGS returned EOPNOTSUPP if userspace is actually trying to
*set* one of the unsettable flags (i.e. it isn't set already)? I believe
this would therefore not break chattr(1), as flags that are retrieved
from GETFLAGS can still be passed into SETFLAGS without error.

If there is some other ABI compatibility that needs to be maintained
that is broken by this, then please let me know. Also, I have not yet
determined whether there are any concerns with calling f2fs_fileattr_get
from inside f2fs_fileattr_set, e.g. speed/performance? so any thoughts
would be greatly appreciated.

Signed-off-by: Harry Austen <[email protected]>
---
fs/f2fs/file.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 3c98ef6af97d..3f3d67c1dfda 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3079,6 +3079,18 @@ int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
return 0;
}

+static bool f2fs_contains_unsettable_flags_not_already_set(struct dentry *dentry, u32 fsflags)
+{
+ struct fileattr old;
+
+ /* Get current file attribute flags */
+ f2fs_fileattr_get(dentry, &old);
+ /* Mask away flags that are already set */
+ fsflags &= ~old.flags;
+ /* Return true if any of the remaining flags are unsettable */
+ return (fsflags & ~F2FS_SETTABLE_FS_FL);
+}
+
int f2fs_fileattr_set(struct user_namespace *mnt_userns,
struct dentry *dentry, struct fileattr *fa)
{
@@ -3093,6 +3105,8 @@ int f2fs_fileattr_set(struct user_namespace *mnt_userns,
return -ENOSPC;
if (fsflags & ~F2FS_GETTABLE_FS_FL)
return -EOPNOTSUPP;
+ if (f2fs_contains_unsettable_flags_not_already_set(dentry, fsflags))
+ return -EOPNOTSUPP;
fsflags &= F2FS_SETTABLE_FS_FL;
if (!fa->flags_valid)
mask &= FS_COMMON_FL;
--
2.35.1


2022-02-01 20:48:40

by Eric Biggers

[permalink] [raw]
Subject: Re: [RFC PATCH] f2fs: disallow setting unsettable file attributes

On Sun, Jan 30, 2022 at 05:21:39PM +0000, Harry Austen wrote:
> After Eric kindly pointed out the reasons why my initial kernel patch
> attempt was incorrect
> (https://lore.kernel.org/lkml/[email protected]/), I had a
> rethink as to if the current implementation could be improved in any
> way.
>
> I wondered whether something along the lines of the following patch
> would be more acceptable? It is intentionally verbose in order to
> demonstrate the concept as this is intended purely as an RFC.
>
> What if SETFLAGS returned EOPNOTSUPP if userspace is actually trying to
> *set* one of the unsettable flags (i.e. it isn't set already)? I believe
> this would therefore not break chattr(1), as flags that are retrieved
> from GETFLAGS can still be passed into SETFLAGS without error.
>
> If there is some other ABI compatibility that needs to be maintained
> that is broken by this, then please let me know. Also, I have not yet
> determined whether there are any concerns with calling f2fs_fileattr_get
> from inside f2fs_fileattr_set, e.g. speed/performance? so any thoughts
> would be greatly appreciated.
>
> Signed-off-by: Harry Austen <[email protected]>
> ---
> fs/f2fs/file.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)

This makes sense, but this ioctl isn't f2fs-specific; it's implemented by other
filesystems, most notably ext2/ext4 where it originated. f2fs shouldn't have
different behavior for the same ioctl. If you want to change this ioctl, you
need to start a wider discussion (including the linux-fsdevel and linux-ext4
mailing lists) where the change is proposed for all filesystems.

- Eric