|
@@ -46,18 +46,22 @@ xattr_permission(struct inode *inode, const char *name, int mask)
|
|
|
return 0;
|
|
|
|
|
|
/*
|
|
|
- * The trusted.* namespace can only be accessed by a privileged user.
|
|
|
+ * The trusted.* namespace can only be accessed by privileged users.
|
|
|
*/
|
|
|
- if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
|
|
|
- return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
|
|
|
+ if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
|
|
|
+ if (!capable(CAP_SYS_ADMIN))
|
|
|
+ return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- /* In user.* namespace, only regular files and directories can have
|
|
|
+ /*
|
|
|
+ * In the user.* namespace, only regular files and directories can have
|
|
|
* extended attributes. For sticky directories, only the owner and
|
|
|
- * privileged user can write attributes.
|
|
|
+ * 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))
|
|
|
- return -EPERM;
|
|
|
+ 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))
|
|
|
return -EPERM;
|