|
@@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * The trusted.* namespace can only accessed by a privilegued user.
|
|
|
|
|
|
+ * The trusted.* namespace can only be accessed by a privileged user.
|
|
*/
|
|
*/
|
|
if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
|
|
if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
|
|
return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
|
|
return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
|
|
|
|
|
|
|
|
+ /* In user.* namespace, only regular files and directories can have
|
|
|
|
+ * extended attributes. For sticky directories, only the owner and
|
|
|
|
+ * privileged user can write attributes.
|
|
|
|
+ */
|
|
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
|
|
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
|
|
- if (!S_ISREG(inode->i_mode) &&
|
|
|
|
- (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
|
|
|
|
|
|
+ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
|
|
|
|
+ return -EPERM;
|
|
|
|
+ if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
|
|
|
|
+ (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) &&
|
|
|
|
+ !capable(CAP_FOWNER))
|
|
return -EPERM;
|
|
return -EPERM;
|
|
}
|
|
}
|
|
|
|
|