From d7a5118635e725d195843bda80cc5c964d93ef31 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Wed, 7 Sep 2022 16:34:21 -0400 Subject: NFSv4.2: Update mode bits after ALLOCATE and DEALLOCATE The fallocate call invalidates suid and sgid bits as part of normal operation. We need to mark the mode bits as invalid when using fallocate with an suid so these will be updated the next time the user looks at them. This fixes xfstests generic/683 and generic/684. Reported-by: Yue Cui Fixes: 913eca1aea87 ("NFS: Fallocate should use the nfs4_fattr_bitmap") Signed-off-by: Anna Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/internal.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'fs/nfs/internal.h') diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 0cabc7f07d9a..316067636434 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -604,6 +604,31 @@ static inline gfp_t nfs_io_gfp_mask(void) return GFP_KERNEL; } +/* + * Special version of should_remove_suid() that ignores capabilities. + */ +static inline int nfs_should_remove_suid(const struct inode *inode) +{ + umode_t mode = inode->i_mode; + int kill = 0; + + /* suid always must be killed */ + if (unlikely(mode & S_ISUID)) + kill = ATTR_KILL_SUID; + + /* + * sgid without any exec bits is just a mandatory locking mark; leave + * it alone. If some exec bits are set, it's a real sgid; kill it. + */ + if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) + kill |= ATTR_KILL_SGID; + + if (unlikely(kill && S_ISREG(mode))) + return kill; + + return 0; +} + /* unlink.c */ extern struct rpc_task * nfs_async_rename(struct inode *old_dir, struct inode *new_dir, -- cgit v1.2.3