aboutsummaryrefslogtreecommitdiff
path: root/fs/nfs/internal.h
diff options
context:
space:
mode:
authorWolfram Sang2022-09-27 21:33:37 +0200
committerWolfram Sang2022-09-27 21:33:37 +0200
commit85f17d677f6c40069287617630f202eb20fcfe36 (patch)
treea0a7de12ddf19068b14124d7a64d79cf697e0710 /fs/nfs/internal.h
parent2dec3a7a7beb23ec11b23986e0e331913d621ff1 (diff)
parentf76349cf41451c5c42a99f18a9163377e4b364ff (diff)
Merge branch 'master' into i2c/for-mergewindow
Diffstat (limited to 'fs/nfs/internal.h')
-rw-r--r--fs/nfs/internal.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 27c720d71b4e..898dd95bc7a7 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -606,6 +606,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,