Skip to content

Commit

Permalink
xattr: allow setting user.* attributes on symlinks by owner
Browse files Browse the repository at this point in the history
Kvmtool and clear containers supports using user attributes to label host
files with the virtual uid/guid of the file in the container. This allows an
end user to manage their files and a complete uid space without all the ugly
namespace stuff.

The one gap in the support is symlinks because an end user can change the
ownership of a symbolic link. We support attributes on these files as you
can already (as root) set security attributes on them.

The current rules seem slightly over-paranoid and as we have a use case this
patch enables updating the attributes on a symbolic link IFF you are the
owner of the synlink (as permissions are not usually meaningful on the link
itself).

Signed-off-by: Alan Cox <alan@linux.intel.com>
  • Loading branch information
Alan Cox authored and heftig committed Oct 12, 2020
1 parent a93d40d commit f50081c
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,17 @@ xattr_permission(struct inode *inode, const char *name, int mask)
}

/*
* In the user.* namespace, only regular files and directories can have
* extended attributes. For sticky directories, only the owner and
* privileged users can write attributes.
* In the user.* namespace, only regular files, symbolic links, and
* directories can have extended attributes. For symbolic links and
* sticky directories, only the owner and privileged users can write
* attributes.
*/
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && !S_ISLNK(inode->i_mode))
return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
(mask & MAY_WRITE) && !inode_owner_or_capable(inode))
if (((S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX))
|| S_ISLNK(inode->i_mode)) && (mask & MAY_WRITE)
&& !inode_owner_or_capable(inode))
return -EPERM;
}

Expand Down

0 comments on commit f50081c

Please sign in to comment.