[Devel] [PATCH 06/10] user namespaces: hook fs/attr.c
Serge E. Hallyn
serue at us.ibm.com
Fri Aug 22 12:46:25 PDT 2008
Hook fs/attr.c so things like chown are properly handled. Note this is only
for permission checks. We'll need to hook ext3_setattr to get the right
uids updated.
Signed-off-by: Serge Hallyn <serue at us.ibm.com>
---
fs/attr.c | 28 +++++++++++++++++++---------
include/linux/sched.h | 1 +
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/fs/attr.c b/fs/attr.c
index 26c71ba..072d367 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -22,6 +22,11 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
{
int retval = -EPERM;
unsigned int ia_valid = attr->ia_valid;
+ uid_t iuid;
+ gid_t igid;
+
+ if (!s_convert_uid_gid(inode, current_userns(), &iuid, &igid))
+ return -EPERM;
/* If force is set do it anyway. */
if (ia_valid & ATTR_FORCE)
@@ -29,30 +34,30 @@ 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))
+ (current->fsuid != iuid ||
+ attr->ia_uid != iuid) && !s_is_capable(inode, current_userns(), CAP_CHOWN))
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))
+ (current->fsuid != iuid ||
+ (!in_group_p(attr->ia_gid) && attr->ia_gid != igid)) &&
+ !s_is_capable(inode, current_userns(), CAP_CHOWN))
goto error;
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
- if (!is_owner_or_cap(inode))
+ if (current->fsuid != iuid || !s_is_capable(inode, current_userns(), CAP_FOWNER))
goto error;
/* Also check the setgid bit! */
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
- inode->i_gid) && !capable(CAP_FSETID))
+ igid) && !s_is_capable(inode, current_userns(), CAP_FSETID))
attr->ia_mode &= ~S_ISGID;
}
/* Check for setting the inode time. */
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
- if (!is_owner_or_cap(inode))
+ if (current->fsuid != iuid || !s_is_capable(inode, current_userns(), CAP_FOWNER))
goto error;
}
fine:
@@ -66,6 +71,11 @@ EXPORT_SYMBOL(inode_change_ok);
int inode_setattr(struct inode * inode, struct iattr * attr)
{
unsigned int ia_valid = attr->ia_valid;
+ uid_t iuid;
+ gid_t igid;
+
+ if (!s_convert_uid_gid(inode, current_userns(), &iuid, &igid))
+ return -EPERM;
if (ia_valid & ATTR_SIZE &&
attr->ia_size != i_size_read(inode)) {
@@ -90,7 +100,7 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
if (ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode;
- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+ if (!in_group_p(igid) && !s_is_capable(inode, current_userns(), CAP_FSETID))
mode &= ~S_ISGID;
inode->i_mode = mode;
}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a2f1356..f557535 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -611,6 +611,7 @@ struct user_struct {
#endif
};
+#define current_userns() (current->user->user_ns)
extern int uids_sysfs_init(void);
extern struct user_struct *find_user(uid_t);
--
1.5.4.3
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list