forked from mirrors/linux
		
	userns: Allow chown and setgid preservation
- 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>
This commit is contained in:
		
							parent
							
								
									5eaf563e53
								
							
						
					
					
						commit
						7fa294c899
					
				
					 1 changed files with 7 additions and 4 deletions
				
			
		
							
								
								
									
										11
									
								
								fs/attr.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								fs/attr.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -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. */
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue