| From: |
| Niraj Kumar <niraj17@gmail.com> |
| To: |
| linux-fsdevel@vger.kernel.org |
| Subject: |
| [PATCH] add unrestricted_chown option to vfs (mount) |
| Date: |
| Tue, 9 Dec 2008 09:57:25 +0530 |
| Message-ID: |
| <20081209042725.GA31729@niraj-laptop> |
| Cc: |
| nick.couchman@seakr.com, hch@lst.de |
| Archive‑link: | |
Article |
Unrestricted chown: adds "unrestricted_chown" mount option.
Add a new unrestricted_chown mount option to the VFS. This option is
used to disable the Posix _POSIX_CHOWN_RESTRICTED chown option on a given
filesystem which forbids non-privilegued users to give away files.
This is currently implemented by XFS as a sysctl, but making it per
filesystem and available not just for XFS makes more sense. This has
also been requested in http://oss.sgi.com/bugzilla/show_bug.cgi?id=768.
See http://www.opengroup.org/onlinepubs/009695399/functions/c...
for details. A patch to util-linux-ng to add the new mount option
is also beeing submitted.
This patch is on top of 2.6.28-rc5.
Signed-off-by: Niraj Kumar <niraj17@gmail.com>
diff --git a/fs/attr.c b/fs/attr.c
index 7a83819..4547563 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -30,15 +30,27 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
/* Make sure a caller can chown. */
if ((ia_valid & ATTR_UID) &&
(current->fsuid != inode->i_uid ||
- attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
- goto error;
+ attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) {
+ /* if "unrestricted_chown" is set, make sure owner can chown */
+ if (!((inode->i_sb->s_flags & MS_UNRESTRICTED_CHOWN) &&
+ (current->fsuid == inode->i_uid)))
+ goto error;
+ }
/* Make sure caller can chgrp. */
if ((ia_valid & ATTR_GID) &&
(current->fsuid != inode->i_uid ||
(!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
- !capable(CAP_CHOWN))
- goto error;
+ !capable(CAP_CHOWN)) {
+ /*
+ * if "unrestricted_chown" is set, make sure the owner can
+ * change the group id only if he is a member of that group.
+ */
+ if (!((inode->i_sb->s_flags & MS_UNRESTRICTED_CHOWN) &&
+ (current->fsuid == inode->i_uid &&
+ in_group_p(attr->ia_gid))))
+ goto error;
+ }
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
diff --git a/fs/namespace.c b/fs/namespace.c
index 65b3dc8..3da02c3 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -757,6 +757,7 @@ static int show_sb_opts(struct seq_file *m, struct super_block *sb)
{ MS_SYNCHRONOUS, ",sync" },
{ MS_DIRSYNC, ",dirsync" },
{ MS_MANDLOCK, ",mand" },
+ { MS_UNRESTRICTED_CHOWN, ",unrestricted_chown" },
{ 0, NULL }
};
const struct proc_fs_info *fs_infop;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0dcdd94..090697b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -119,6 +119,7 @@ extern int dir_notify_enable;
#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#define MS_UNRESTRICTED_CHOWN 256 /* Unrestricted chown */
#define MS_NOATIME 1024 /* Do not update access times. */
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
@@ -141,7 +142,8 @@ extern int dir_notify_enable;
/*
* Superblock flags that can be altered by MS_REMOUNT
*/
-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\
+ MS_UNRESTRICTED_CHOWN)
/*
* Old magic mount flag and mask
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html