summaryrefslogtreecommitdiff
path: root/fs/nfs/internal.h
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2022-10-16 16:06:53 -0700
committerAndrew Morton <akpm@linux-foundation.org>2022-10-16 16:06:53 -0700
commit280330fac48280e16454cfa46c368af4812ad79c (patch)
tree18b9ed796c57e3929e50b9b03f2c6501740b03d6 /fs/nfs/internal.h
parentd0d51a97063db4704a5ef6bc978dddab1636a306 (diff)
parent4fe89d07dcc2804c8b562f6c7896a45643d34b2f (diff)
Merge branch 'master' into mm-hotfixes-stable
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,