diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xattr.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 395635100f77..0901bdc2ce24 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
48 | return 0; | 48 | return 0; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * The trusted.* namespace can only accessed by a privilegued user. | 51 | * The trusted.* namespace can only be accessed by a privileged user. |
52 | */ | 52 | */ |
53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | 53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) |
54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); |
55 | 55 | ||
56 | /* In user.* namespace, only regular files and directories can have | ||
57 | * extended attributes. For sticky directories, only the owner and | ||
58 | * privileged user can write attributes. | ||
59 | */ | ||
56 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { | 60 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
57 | if (!S_ISREG(inode->i_mode) && | 61 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
58 | (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) | 62 | return -EPERM; |
63 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && | ||
64 | (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) && | ||
65 | !capable(CAP_FOWNER)) | ||
59 | return -EPERM; | 66 | return -EPERM; |
60 | } | 67 | } |
61 | 68 | ||