diff --git a/[refs] b/[refs] index 8fa3014f2ea4..48fa88f11ad5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8ce08464d2c749610a52c4d6c7c11080a7eaaef1 +refs/heads/master: f1f2d8713d16a1e198880bbc716eb24fae09c858 diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 395635100f77..0901bdc2ce24 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask) 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)) 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 (!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; }