Skip to content

Commit

Permalink
internal: add may_write_xattr()
Browse files Browse the repository at this point in the history
Split out the generic checks whether an inode allows writing xattrs. Since
security.* and system.* xattrs don't have any restrictions and we're going
to split out posix acls into a dedicated api we will use this helper to
check whether we can write posix acls.

Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
  • Loading branch information
Christian Brauner committed Oct 20, 2022
1 parent a56df5d commit 56851bc
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
1 change: 1 addition & 0 deletions fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,5 +232,6 @@ ssize_t do_getxattr(struct user_namespace *mnt_userns,
int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct xattr_ctx *ctx);
int may_write_xattr(struct user_namespace *mnt_userns, struct inode *inode);

ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos);
43 changes: 30 additions & 13 deletions fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,31 @@ xattr_resolve_name(struct inode *inode, const char **name)
return ERR_PTR(-EOPNOTSUPP);
}

/**
* may_write_xattr - check whether inode allows writing xattr
* @mnt_userns: User namespace of the mount the inode was found from
* @inode: the inode on which to set an xattr
*
* Check whether the inode allows writing xattrs. Specifically, we can never
* set or remove an extended attribute on a read-only filesystem or on an
* immutable / append-only inode.
*
* We also need to ensure that the inode has a mapping in the mount to
* not risk writing back invalid i_{g,u}id values.
*
* Return: On success zero is returned. On error a negative errno is returned.
*/
int may_write_xattr(struct user_namespace *mnt_userns, struct inode *inode)
{
if (IS_IMMUTABLE(inode))
return -EPERM;
if (IS_APPEND(inode))
return -EPERM;
if (HAS_UNMAPPED_ID(mnt_userns, inode))
return -EPERM;
return 0;
}

/*
* Check permissions for extended attribute access. This is a bit complicated
* because different namespaces have very different rules.
Expand All @@ -88,20 +113,12 @@ static int
xattr_permission(struct user_namespace *mnt_userns, struct inode *inode,
const char *name, int mask)
{
/*
* We can never set or remove an extended attribute on a read-only
* filesystem or on an immutable / append-only inode.
*/
if (mask & MAY_WRITE) {
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
/*
* Updating an xattr will likely cause i_uid and i_gid
* to be writen back improperly if their true value is
* unknown to the vfs.
*/
if (HAS_UNMAPPED_ID(mnt_userns, inode))
return -EPERM;
int ret;

ret = may_write_xattr(mnt_userns, inode);
if (ret)
return ret;
}

/*
Expand Down

0 comments on commit 56851bc

Please sign in to comment.