Skip to content

Commit

Permalink
userns: Allow chown and setgid preservation
Browse files Browse the repository at this point in the history
- Allow chown if CAP_CHOWN is present in the current user namespace
  and the uid of the inode maps into the current user namespace, and
  the destination uid or gid maps into the current user namespace.

- Allow perserving setgid when changing an inode if CAP_FSETID is
  present in the current user namespace and the owner of the file has
  a mapping into the current user namespace.

Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
ebiederm committed Nov 20, 2012
1 parent 5eaf563 commit 7fa294c
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions fs/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
/* Make sure a caller can chown. */
if ((ia_valid & ATTR_UID) &&
(!uid_eq(current_fsuid(), inode->i_uid) ||
!uid_eq(attr->ia_uid, inode->i_uid)) && !capable(CAP_CHOWN))
!uid_eq(attr->ia_uid, inode->i_uid)) &&
!inode_capable(inode, CAP_CHOWN))
return -EPERM;

/* Make sure caller can chgrp. */
if ((ia_valid & ATTR_GID) &&
(!uid_eq(current_fsuid(), inode->i_uid) ||
(!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
!capable(CAP_CHOWN))
!inode_capable(inode, CAP_CHOWN))
return -EPERM;

/* Make sure a caller can chmod. */
Expand All @@ -65,7 +66,8 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
return -EPERM;
/* Also check the setgid bit! */
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
inode->i_gid) && !capable(CAP_FSETID))
inode->i_gid) &&
!inode_capable(inode, CAP_FSETID))
attr->ia_mode &= ~S_ISGID;
}

Expand Down Expand Up @@ -157,7 +159,8 @@ void setattr_copy(struct inode *inode, const 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(inode->i_gid) &&
!inode_capable(inode, CAP_FSETID))
mode &= ~S_ISGID;
inode->i_mode = mode;
}
Expand Down

0 comments on commit 7fa294c

Please sign in to comment.