diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-12-02 08:44:36 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-12-06 21:33:52 -0500 |
commit | 98e9cb5711c68223f0e4d5201b9a6add255ec550 (patch) | |
tree | 12fee55d296fc85a6e8188368ca4944fc4d913a8 | |
parent | 97d79299223baab330b194437e676d301f12d5f6 (diff) |
vfs: Distinguish between full xattr names and proper prefixes
Add an additional "name" field to struct xattr_handler. When the name
is set, the handler matches attributes with exactly that name. When the
prefix is set instead, the handler matches attributes with the given
prefix and with a non-empty suffix.
This patch should avoid bugs like the one fixed in commit c361016a in
the future.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: James Morris <james.l.morris@oracle.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/9p/acl.c | 16 | ||||
-rw-r--r-- | fs/9p/xattr.c | 4 | ||||
-rw-r--r-- | fs/ext2/xattr_security.c | 4 | ||||
-rw-r--r-- | fs/ext2/xattr_trusted.c | 4 | ||||
-rw-r--r-- | fs/ext2/xattr_user.c | 4 | ||||
-rw-r--r-- | fs/ext4/xattr_security.c | 4 | ||||
-rw-r--r-- | fs/ext4/xattr_trusted.c | 4 | ||||
-rw-r--r-- | fs/ext4/xattr_user.c | 4 | ||||
-rw-r--r-- | fs/f2fs/xattr.c | 20 | ||||
-rw-r--r-- | fs/f2fs/xattr.h | 2 | ||||
-rw-r--r-- | fs/hfsplus/xattr.c | 12 | ||||
-rw-r--r-- | fs/jffs2/security.c | 6 | ||||
-rw-r--r-- | fs/jffs2/xattr_trusted.c | 4 | ||||
-rw-r--r-- | fs/jffs2/xattr_user.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 8 | ||||
-rw-r--r-- | fs/ocfs2/xattr.c | 17 | ||||
-rw-r--r-- | fs/posix_acl.c | 10 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 3 | ||||
-rw-r--r-- | fs/squashfs/xattr.c | 3 | ||||
-rw-r--r-- | fs/xattr.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_xattr.c | 6 | ||||
-rw-r--r-- | include/linux/xattr.h | 11 |
22 files changed, 47 insertions, 130 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 6ff30b14bc76..9da967f38387 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
@@ -220,15 +220,12 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler, | |||
220 | struct posix_acl *acl; | 220 | struct posix_acl *acl; |
221 | int error; | 221 | int error; |
222 | 222 | ||
223 | if (strcmp(name, "") != 0) | ||
224 | return -EINVAL; | ||
225 | |||
226 | v9ses = v9fs_dentry2v9ses(dentry); | 223 | v9ses = v9fs_dentry2v9ses(dentry); |
227 | /* | 224 | /* |
228 | * We allow set/get/list of acl when access=client is not specified | 225 | * We allow set/get/list of acl when access=client is not specified |
229 | */ | 226 | */ |
230 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | 227 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) |
231 | return v9fs_xattr_get(dentry, handler->prefix, buffer, size); | 228 | return v9fs_xattr_get(dentry, handler->name, buffer, size); |
232 | 229 | ||
233 | acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags); | 230 | acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags); |
234 | if (IS_ERR(acl)) | 231 | if (IS_ERR(acl)) |
@@ -250,16 +247,13 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, | |||
250 | struct v9fs_session_info *v9ses; | 247 | struct v9fs_session_info *v9ses; |
251 | struct inode *inode = d_inode(dentry); | 248 | struct inode *inode = d_inode(dentry); |
252 | 249 | ||
253 | if (strcmp(name, "") != 0) | ||
254 | return -EINVAL; | ||
255 | |||
256 | v9ses = v9fs_dentry2v9ses(dentry); | 250 | v9ses = v9fs_dentry2v9ses(dentry); |
257 | /* | 251 | /* |
258 | * set the attribute on the remote. Without even looking at the | 252 | * set the attribute on the remote. Without even looking at the |
259 | * xattr value. We leave it to the server to validate | 253 | * xattr value. We leave it to the server to validate |
260 | */ | 254 | */ |
261 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | 255 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) |
262 | return v9fs_xattr_set(dentry, handler->prefix, value, size, | 256 | return v9fs_xattr_set(dentry, handler->name, value, size, |
263 | flags); | 257 | flags); |
264 | 258 | ||
265 | if (S_ISLNK(inode->i_mode)) | 259 | if (S_ISLNK(inode->i_mode)) |
@@ -319,7 +313,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, | |||
319 | default: | 313 | default: |
320 | BUG(); | 314 | BUG(); |
321 | } | 315 | } |
322 | retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags); | 316 | retval = v9fs_xattr_set(dentry, handler->name, value, size, flags); |
323 | if (!retval) | 317 | if (!retval) |
324 | set_cached_acl(inode, handler->flags, acl); | 318 | set_cached_acl(inode, handler->flags, acl); |
325 | err_out: | 319 | err_out: |
@@ -328,14 +322,14 @@ err_out: | |||
328 | } | 322 | } |
329 | 323 | ||
330 | const struct xattr_handler v9fs_xattr_acl_access_handler = { | 324 | const struct xattr_handler v9fs_xattr_acl_access_handler = { |
331 | .prefix = XATTR_NAME_POSIX_ACL_ACCESS, | 325 | .name = XATTR_NAME_POSIX_ACL_ACCESS, |
332 | .flags = ACL_TYPE_ACCESS, | 326 | .flags = ACL_TYPE_ACCESS, |
333 | .get = v9fs_xattr_get_acl, | 327 | .get = v9fs_xattr_get_acl, |
334 | .set = v9fs_xattr_set_acl, | 328 | .set = v9fs_xattr_set_acl, |
335 | }; | 329 | }; |
336 | 330 | ||
337 | const struct xattr_handler v9fs_xattr_acl_default_handler = { | 331 | const struct xattr_handler v9fs_xattr_acl_default_handler = { |
338 | .prefix = XATTR_NAME_POSIX_ACL_DEFAULT, | 332 | .name = XATTR_NAME_POSIX_ACL_DEFAULT, |
339 | .flags = ACL_TYPE_DEFAULT, | 333 | .flags = ACL_TYPE_DEFAULT, |
340 | .get = v9fs_xattr_get_acl, | 334 | .get = v9fs_xattr_get_acl, |
341 | .set = v9fs_xattr_set_acl, | 335 | .set = v9fs_xattr_set_acl, |
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c index e3d026ac382e..9dd9b47a6c1a 100644 --- a/fs/9p/xattr.c +++ b/fs/9p/xattr.c | |||
@@ -143,8 +143,6 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler, | |||
143 | { | 143 | { |
144 | const char *full_name = xattr_full_name(handler, name); | 144 | const char *full_name = xattr_full_name(handler, name); |
145 | 145 | ||
146 | if (strcmp(name, "") == 0) | ||
147 | return -EINVAL; | ||
148 | return v9fs_xattr_get(dentry, full_name, buffer, size); | 146 | return v9fs_xattr_get(dentry, full_name, buffer, size); |
149 | } | 147 | } |
150 | 148 | ||
@@ -154,8 +152,6 @@ static int v9fs_xattr_handler_set(const struct xattr_handler *handler, | |||
154 | { | 152 | { |
155 | const char *full_name = xattr_full_name(handler, name); | 153 | const char *full_name = xattr_full_name(handler, name); |
156 | 154 | ||
157 | if (strcmp(name, "") == 0) | ||
158 | return -EINVAL; | ||
159 | return v9fs_xattr_set(dentry, full_name, value, size, flags); | 155 | return v9fs_xattr_set(dentry, full_name, value, size, flags); |
160 | } | 156 | } |
161 | 157 | ||
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index dfb08750370d..118bf231bc7f 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
@@ -28,8 +28,6 @@ ext2_xattr_security_get(const struct xattr_handler *handler, | |||
28 | struct dentry *dentry, const char *name, | 28 | struct dentry *dentry, const char *name, |
29 | void *buffer, size_t size) | 29 | void *buffer, size_t size) |
30 | { | 30 | { |
31 | if (strcmp(name, "") == 0) | ||
32 | return -EINVAL; | ||
33 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, | 31 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, |
34 | buffer, size); | 32 | buffer, size); |
35 | } | 33 | } |
@@ -39,8 +37,6 @@ ext2_xattr_security_set(const struct xattr_handler *handler, | |||
39 | struct dentry *dentry, const char *name, | 37 | struct dentry *dentry, const char *name, |
40 | const void *value, size_t size, int flags) | 38 | const void *value, size_t size, int flags) |
41 | { | 39 | { |
42 | if (strcmp(name, "") == 0) | ||
43 | return -EINVAL; | ||
44 | return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, | 40 | return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, |
45 | value, size, flags); | 41 | value, size, flags); |
46 | } | 42 | } |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 3150dd3a7859..3f8f2bc6539e 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
@@ -32,8 +32,6 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler, | |||
32 | struct dentry *dentry, const char *name, | 32 | struct dentry *dentry, const char *name, |
33 | void *buffer, size_t size) | 33 | void *buffer, size_t size) |
34 | { | 34 | { |
35 | if (strcmp(name, "") == 0) | ||
36 | return -EINVAL; | ||
37 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, | 35 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, |
38 | buffer, size); | 36 | buffer, size); |
39 | } | 37 | } |
@@ -43,8 +41,6 @@ ext2_xattr_trusted_set(const struct xattr_handler *handler, | |||
43 | struct dentry *dentry, const char *name, | 41 | struct dentry *dentry, const char *name, |
44 | const void *value, size_t size, int flags) | 42 | const void *value, size_t size, int flags) |
45 | { | 43 | { |
46 | if (strcmp(name, "") == 0) | ||
47 | return -EINVAL; | ||
48 | return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, | 44 | return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, |
49 | value, size, flags); | 45 | value, size, flags); |
50 | } | 46 | } |
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 339a49bbb8ef..afd45ab1218c 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
@@ -34,8 +34,6 @@ ext2_xattr_user_get(const struct xattr_handler *handler, | |||
34 | struct dentry *dentry, const char *name, | 34 | struct dentry *dentry, const char *name, |
35 | void *buffer, size_t size) | 35 | void *buffer, size_t size) |
36 | { | 36 | { |
37 | if (strcmp(name, "") == 0) | ||
38 | return -EINVAL; | ||
39 | if (!test_opt(dentry->d_sb, XATTR_USER)) | 37 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
40 | return -EOPNOTSUPP; | 38 | return -EOPNOTSUPP; |
41 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_USER, | 39 | return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_USER, |
@@ -47,8 +45,6 @@ ext2_xattr_user_set(const struct xattr_handler *handler, | |||
47 | struct dentry *dentry, const char *name, | 45 | struct dentry *dentry, const char *name, |
48 | const void *value, size_t size, int flags) | 46 | const void *value, size_t size, int flags) |
49 | { | 47 | { |
50 | if (strcmp(name, "") == 0) | ||
51 | return -EINVAL; | ||
52 | if (!test_opt(dentry->d_sb, XATTR_USER)) | 48 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
53 | return -EOPNOTSUPP; | 49 | return -EOPNOTSUPP; |
54 | 50 | ||
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 36f4c1a84c21..195abc4a88bb 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c | |||
@@ -33,8 +33,6 @@ ext4_xattr_security_get(const struct xattr_handler *handler, | |||
33 | struct dentry *dentry, const char *name, | 33 | struct dentry *dentry, const char *name, |
34 | void *buffer, size_t size) | 34 | void *buffer, size_t size) |
35 | { | 35 | { |
36 | if (strcmp(name, "") == 0) | ||
37 | return -EINVAL; | ||
38 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, | 36 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, |
39 | name, buffer, size); | 37 | name, buffer, size); |
40 | } | 38 | } |
@@ -44,8 +42,6 @@ ext4_xattr_security_set(const struct xattr_handler *handler, | |||
44 | struct dentry *dentry, const char *name, | 42 | struct dentry *dentry, const char *name, |
45 | const void *value, size_t size, int flags) | 43 | const void *value, size_t size, int flags) |
46 | { | 44 | { |
47 | if (strcmp(name, "") == 0) | ||
48 | return -EINVAL; | ||
49 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, | 45 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, |
50 | name, value, size, flags); | 46 | name, value, size, flags); |
51 | } | 47 | } |
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index 488089053342..121fdf9fdc02 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c | |||
@@ -36,8 +36,6 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler, | |||
36 | struct dentry *dentry, const char *name, void *buffer, | 36 | struct dentry *dentry, const char *name, void *buffer, |
37 | size_t size) | 37 | size_t size) |
38 | { | 38 | { |
39 | if (strcmp(name, "") == 0) | ||
40 | return -EINVAL; | ||
41 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, | 39 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, |
42 | name, buffer, size); | 40 | name, buffer, size); |
43 | } | 41 | } |
@@ -47,8 +45,6 @@ ext4_xattr_trusted_set(const struct xattr_handler *handler, | |||
47 | struct dentry *dentry, const char *name, | 45 | struct dentry *dentry, const char *name, |
48 | const void *value, size_t size, int flags) | 46 | const void *value, size_t size, int flags) |
49 | { | 47 | { |
50 | if (strcmp(name, "") == 0) | ||
51 | return -EINVAL; | ||
52 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, | 48 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, |
53 | name, value, size, flags); | 49 | name, value, size, flags); |
54 | } | 50 | } |
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index d2dec3364062..577fc122d884 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c | |||
@@ -35,8 +35,6 @@ ext4_xattr_user_get(const struct xattr_handler *handler, | |||
35 | struct dentry *dentry, const char *name, | 35 | struct dentry *dentry, const char *name, |
36 | void *buffer, size_t size) | 36 | void *buffer, size_t size) |
37 | { | 37 | { |
38 | if (strcmp(name, "") == 0) | ||
39 | return -EINVAL; | ||
40 | if (!test_opt(dentry->d_sb, XATTR_USER)) | 38 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
41 | return -EOPNOTSUPP; | 39 | return -EOPNOTSUPP; |
42 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_USER, | 40 | return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_USER, |
@@ -48,8 +46,6 @@ ext4_xattr_user_set(const struct xattr_handler *handler, | |||
48 | struct dentry *dentry, const char *name, | 46 | struct dentry *dentry, const char *name, |
49 | const void *value, size_t size, int flags) | 47 | const void *value, size_t size, int flags) |
50 | { | 48 | { |
51 | if (strcmp(name, "") == 0) | ||
52 | return -EINVAL; | ||
53 | if (!test_opt(dentry->d_sb, XATTR_USER)) | 49 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
54 | return -EOPNOTSUPP; | 50 | return -EOPNOTSUPP; |
55 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER, | 51 | return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER, |
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 862368a32e53..21cfe516034f 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c | |||
@@ -30,6 +30,7 @@ static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler, | |||
30 | const char *name, size_t len) | 30 | const char *name, size_t len) |
31 | { | 31 | { |
32 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); | 32 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); |
33 | const char *prefix; | ||
33 | int total_len, prefix_len; | 34 | int total_len, prefix_len; |
34 | 35 | ||
35 | switch (handler->flags) { | 36 | switch (handler->flags) { |
@@ -47,10 +48,11 @@ static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler, | |||
47 | return -EINVAL; | 48 | return -EINVAL; |
48 | } | 49 | } |
49 | 50 | ||
50 | prefix_len = strlen(handler->prefix); | 51 | prefix = xattr_prefix(handler); |
52 | prefix_len = strlen(prefix); | ||
51 | total_len = prefix_len + len + 1; | 53 | total_len = prefix_len + len + 1; |
52 | if (list && total_len <= list_size) { | 54 | if (list && total_len <= list_size) { |
53 | memcpy(list, handler->prefix, prefix_len); | 55 | memcpy(list, prefix, prefix_len); |
54 | memcpy(list + prefix_len, name, len); | 56 | memcpy(list + prefix_len, name, len); |
55 | list[prefix_len + len] = '\0'; | 57 | list[prefix_len + len] = '\0'; |
56 | } | 58 | } |
@@ -77,8 +79,6 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler, | |||
77 | default: | 79 | default: |
78 | return -EINVAL; | 80 | return -EINVAL; |
79 | } | 81 | } |
80 | if (strcmp(name, "") == 0) | ||
81 | return -EINVAL; | ||
82 | return f2fs_getxattr(d_inode(dentry), handler->flags, name, | 82 | return f2fs_getxattr(d_inode(dentry), handler->flags, name, |
83 | buffer, size, NULL); | 83 | buffer, size, NULL); |
84 | } | 84 | } |
@@ -103,9 +103,6 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler, | |||
103 | default: | 103 | default: |
104 | return -EINVAL; | 104 | return -EINVAL; |
105 | } | 105 | } |
106 | if (strcmp(name, "") == 0) | ||
107 | return -EINVAL; | ||
108 | |||
109 | return f2fs_setxattr(d_inode(dentry), handler->flags, name, | 106 | return f2fs_setxattr(d_inode(dentry), handler->flags, name, |
110 | value, size, NULL, flags); | 107 | value, size, NULL, flags); |
111 | } | 108 | } |
@@ -114,7 +111,7 @@ static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, | |||
114 | struct dentry *dentry, char *list, size_t list_size, | 111 | struct dentry *dentry, char *list, size_t list_size, |
115 | const char *name, size_t len) | 112 | const char *name, size_t len) |
116 | { | 113 | { |
117 | const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; | 114 | const char *xname = F2FS_SYSTEM_ADVISE_NAME; |
118 | size_t size; | 115 | size_t size; |
119 | 116 | ||
120 | size = strlen(xname) + 1; | 117 | size = strlen(xname) + 1; |
@@ -129,9 +126,6 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler, | |||
129 | { | 126 | { |
130 | struct inode *inode = d_inode(dentry); | 127 | struct inode *inode = d_inode(dentry); |
131 | 128 | ||
132 | if (strcmp(name, "") != 0) | ||
133 | return -EINVAL; | ||
134 | |||
135 | if (buffer) | 129 | if (buffer) |
136 | *((char *)buffer) = F2FS_I(inode)->i_advise; | 130 | *((char *)buffer) = F2FS_I(inode)->i_advise; |
137 | return sizeof(char); | 131 | return sizeof(char); |
@@ -143,8 +137,6 @@ static int f2fs_xattr_advise_set(const struct xattr_handler *handler, | |||
143 | { | 137 | { |
144 | struct inode *inode = d_inode(dentry); | 138 | struct inode *inode = d_inode(dentry); |
145 | 139 | ||
146 | if (strcmp(name, "") != 0) | ||
147 | return -EINVAL; | ||
148 | if (!inode_owner_or_capable(inode)) | 140 | if (!inode_owner_or_capable(inode)) |
149 | return -EPERM; | 141 | return -EPERM; |
150 | if (value == NULL) | 142 | if (value == NULL) |
@@ -197,7 +189,7 @@ const struct xattr_handler f2fs_xattr_trusted_handler = { | |||
197 | }; | 189 | }; |
198 | 190 | ||
199 | const struct xattr_handler f2fs_xattr_advise_handler = { | 191 | const struct xattr_handler f2fs_xattr_advise_handler = { |
200 | .prefix = F2FS_SYSTEM_ADVISE_PREFIX, | 192 | .name = F2FS_SYSTEM_ADVISE_NAME, |
201 | .flags = F2FS_XATTR_INDEX_ADVISE, | 193 | .flags = F2FS_XATTR_INDEX_ADVISE, |
202 | .list = f2fs_xattr_advise_list, | 194 | .list = f2fs_xattr_advise_list, |
203 | .get = f2fs_xattr_advise_get, | 195 | .get = f2fs_xattr_advise_get, |
diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 71a7100d5492..79dccc8252dd 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #define F2FS_XATTR_REFCOUNT_MAX 1024 | 27 | #define F2FS_XATTR_REFCOUNT_MAX 1024 |
28 | 28 | ||
29 | /* Name indexes */ | 29 | /* Name indexes */ |
30 | #define F2FS_SYSTEM_ADVISE_PREFIX "system.advise" | 30 | #define F2FS_SYSTEM_ADVISE_NAME "system.advise" |
31 | #define F2FS_XATTR_INDEX_USER 1 | 31 | #define F2FS_XATTR_INDEX_USER 1 |
32 | #define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2 | 32 | #define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2 |
33 | #define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 | 33 | #define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 |
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index e41a010cd89c..ab01530b4930 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c | |||
@@ -431,9 +431,6 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name, | |||
431 | char *xattr_name; | 431 | char *xattr_name; |
432 | int res; | 432 | int res; |
433 | 433 | ||
434 | if (!strcmp(name, "")) | ||
435 | return -EINVAL; | ||
436 | |||
437 | xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | 434 | xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, |
438 | GFP_KERNEL); | 435 | GFP_KERNEL); |
439 | if (!xattr_name) | 436 | if (!xattr_name) |
@@ -589,9 +586,6 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |||
589 | int res; | 586 | int res; |
590 | char *xattr_name; | 587 | char *xattr_name; |
591 | 588 | ||
592 | if (!strcmp(name, "")) | ||
593 | return -EINVAL; | ||
594 | |||
595 | xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | 589 | xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, |
596 | GFP_KERNEL); | 590 | GFP_KERNEL); |
597 | if (!xattr_name) | 591 | if (!xattr_name) |
@@ -853,9 +847,6 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler, | |||
853 | struct dentry *dentry, const char *name, | 847 | struct dentry *dentry, const char *name, |
854 | void *buffer, size_t size) | 848 | void *buffer, size_t size) |
855 | { | 849 | { |
856 | if (!strcmp(name, "")) | ||
857 | return -EINVAL; | ||
858 | |||
859 | /* | 850 | /* |
860 | * Don't allow retrieving properly prefixed attributes | 851 | * Don't allow retrieving properly prefixed attributes |
861 | * by prepending them with "osx." | 852 | * by prepending them with "osx." |
@@ -876,9 +867,6 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler, | |||
876 | struct dentry *dentry, const char *name, | 867 | struct dentry *dentry, const char *name, |
877 | const void *buffer, size_t size, int flags) | 868 | const void *buffer, size_t size, int flags) |
878 | { | 869 | { |
879 | if (!strcmp(name, "")) | ||
880 | return -EINVAL; | ||
881 | |||
882 | /* | 870 | /* |
883 | * Don't allow setting properly prefixed attributes | 871 | * Don't allow setting properly prefixed attributes |
884 | * by prepending them with "osx." | 872 | * by prepending them with "osx." |
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index bf12fe5f83d7..ea79932cd665 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
@@ -52,9 +52,6 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler, | |||
52 | struct dentry *dentry, const char *name, | 52 | struct dentry *dentry, const char *name, |
53 | void *buffer, size_t size) | 53 | void *buffer, size_t size) |
54 | { | 54 | { |
55 | if (!strcmp(name, "")) | ||
56 | return -EINVAL; | ||
57 | |||
58 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, | 55 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, |
59 | name, buffer, size); | 56 | name, buffer, size); |
60 | } | 57 | } |
@@ -63,9 +60,6 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler, | |||
63 | struct dentry *dentry, const char *name, | 60 | struct dentry *dentry, const char *name, |
64 | const void *buffer, size_t size, int flags) | 61 | const void *buffer, size_t size, int flags) |
65 | { | 62 | { |
66 | if (!strcmp(name, "")) | ||
67 | return -EINVAL; | ||
68 | |||
69 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, | 63 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, |
70 | name, buffer, size, flags); | 64 | name, buffer, size, flags); |
71 | } | 65 | } |
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index a562da0d6a26..8b55fe44c777 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c | |||
@@ -20,8 +20,6 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler, | |||
20 | struct dentry *dentry, const char *name, | 20 | struct dentry *dentry, const char *name, |
21 | void *buffer, size_t size) | 21 | void *buffer, size_t size) |
22 | { | 22 | { |
23 | if (!strcmp(name, "")) | ||
24 | return -EINVAL; | ||
25 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, | 23 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, |
26 | name, buffer, size); | 24 | name, buffer, size); |
27 | } | 25 | } |
@@ -30,8 +28,6 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler, | |||
30 | struct dentry *dentry, const char *name, | 28 | struct dentry *dentry, const char *name, |
31 | const void *buffer, size_t size, int flags) | 29 | const void *buffer, size_t size, int flags) |
32 | { | 30 | { |
33 | if (!strcmp(name, "")) | ||
34 | return -EINVAL; | ||
35 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, | 31 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, |
36 | name, buffer, size, flags); | 32 | name, buffer, size, flags); |
37 | } | 33 | } |
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index cbc0472e59a8..b04335b84833 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c | |||
@@ -20,8 +20,6 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler, | |||
20 | struct dentry *dentry, const char *name, | 20 | struct dentry *dentry, const char *name, |
21 | void *buffer, size_t size) | 21 | void *buffer, size_t size) |
22 | { | 22 | { |
23 | if (!strcmp(name, "")) | ||
24 | return -EINVAL; | ||
25 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_USER, | 23 | return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_USER, |
26 | name, buffer, size); | 24 | name, buffer, size); |
27 | } | 25 | } |
@@ -30,8 +28,6 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler, | |||
30 | struct dentry *dentry, const char *name, | 28 | struct dentry *dentry, const char *name, |
31 | const void *buffer, size_t size, int flags) | 29 | const void *buffer, size_t size, int flags) |
32 | { | 30 | { |
33 | if (!strcmp(name, "")) | ||
34 | return -EINVAL; | ||
35 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER, | 31 | return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER, |
36 | name, buffer, size, flags); | 32 | name, buffer, size, flags); |
37 | } | 33 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 89818036f035..f6f40aae92b1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -6253,9 +6253,6 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, | |||
6253 | const void *buf, size_t buflen, | 6253 | const void *buf, size_t buflen, |
6254 | int flags) | 6254 | int flags) |
6255 | { | 6255 | { |
6256 | if (strcmp(key, "") != 0) | ||
6257 | return -EINVAL; | ||
6258 | |||
6259 | return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); | 6256 | return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); |
6260 | } | 6257 | } |
6261 | 6258 | ||
@@ -6263,9 +6260,6 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, | |||
6263 | struct dentry *dentry, const char *key, | 6260 | struct dentry *dentry, const char *key, |
6264 | void *buf, size_t buflen) | 6261 | void *buf, size_t buflen) |
6265 | { | 6262 | { |
6266 | if (strcmp(key, "") != 0) | ||
6267 | return -EINVAL; | ||
6268 | |||
6269 | return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); | 6263 | return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); |
6270 | } | 6264 | } |
6271 | 6265 | ||
@@ -8834,7 +8828,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
8834 | }; | 8828 | }; |
8835 | 8829 | ||
8836 | static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { | 8830 | static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { |
8837 | .prefix = XATTR_NAME_NFSV4_ACL, | 8831 | .name = XATTR_NAME_NFSV4_ACL, |
8838 | .list = nfs4_xattr_list_nfs4_acl, | 8832 | .list = nfs4_xattr_list_nfs4_acl, |
8839 | .get = nfs4_xattr_get_nfs4_acl, | 8833 | .get = nfs4_xattr_get_nfs4_acl, |
8840 | .set = nfs4_xattr_set_nfs4_acl, | 8834 | .set = nfs4_xattr_set_nfs4_acl, |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e9164f09841b..5823f985a662 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -544,8 +544,7 @@ static inline const char *ocfs2_xattr_prefix(int name_index) | |||
544 | 544 | ||
545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) | 545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) |
546 | handler = ocfs2_xattr_handler_map[name_index]; | 546 | handler = ocfs2_xattr_handler_map[name_index]; |
547 | 547 | return handler ? xattr_prefix(handler) : NULL; | |
548 | return handler ? handler->prefix : NULL; | ||
549 | } | 548 | } |
550 | 549 | ||
551 | static u32 ocfs2_xattr_name_hash(struct inode *inode, | 550 | static u32 ocfs2_xattr_name_hash(struct inode *inode, |
@@ -7249,8 +7248,6 @@ static int ocfs2_xattr_security_get(const struct xattr_handler *handler, | |||
7249 | struct dentry *dentry, const char *name, | 7248 | struct dentry *dentry, const char *name, |
7250 | void *buffer, size_t size) | 7249 | void *buffer, size_t size) |
7251 | { | 7250 | { |
7252 | if (strcmp(name, "") == 0) | ||
7253 | return -EINVAL; | ||
7254 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, | 7251 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, |
7255 | name, buffer, size); | 7252 | name, buffer, size); |
7256 | } | 7253 | } |
@@ -7259,9 +7256,6 @@ static int ocfs2_xattr_security_set(const struct xattr_handler *handler, | |||
7259 | struct dentry *dentry, const char *name, | 7256 | struct dentry *dentry, const char *name, |
7260 | const void *value, size_t size, int flags) | 7257 | const void *value, size_t size, int flags) |
7261 | { | 7258 | { |
7262 | if (strcmp(name, "") == 0) | ||
7263 | return -EINVAL; | ||
7264 | |||
7265 | return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, | 7259 | return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, |
7266 | name, value, size, flags); | 7260 | name, value, size, flags); |
7267 | } | 7261 | } |
@@ -7345,8 +7339,6 @@ static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, | |||
7345 | struct dentry *dentry, const char *name, | 7339 | struct dentry *dentry, const char *name, |
7346 | void *buffer, size_t size) | 7340 | void *buffer, size_t size) |
7347 | { | 7341 | { |
7348 | if (strcmp(name, "") == 0) | ||
7349 | return -EINVAL; | ||
7350 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, | 7342 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, |
7351 | name, buffer, size); | 7343 | name, buffer, size); |
7352 | } | 7344 | } |
@@ -7355,9 +7347,6 @@ static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler, | |||
7355 | struct dentry *dentry, const char *name, | 7347 | struct dentry *dentry, const char *name, |
7356 | const void *value, size_t size, int flags) | 7348 | const void *value, size_t size, int flags) |
7357 | { | 7349 | { |
7358 | if (strcmp(name, "") == 0) | ||
7359 | return -EINVAL; | ||
7360 | |||
7361 | return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, | 7350 | return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, |
7362 | name, value, size, flags); | 7351 | name, value, size, flags); |
7363 | } | 7352 | } |
@@ -7398,8 +7387,6 @@ static int ocfs2_xattr_user_get(const struct xattr_handler *handler, | |||
7398 | { | 7387 | { |
7399 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); | 7388 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); |
7400 | 7389 | ||
7401 | if (strcmp(name, "") == 0) | ||
7402 | return -EINVAL; | ||
7403 | if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) | 7390 | if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) |
7404 | return -EOPNOTSUPP; | 7391 | return -EOPNOTSUPP; |
7405 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_USER, name, | 7392 | return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_USER, name, |
@@ -7412,8 +7399,6 @@ static int ocfs2_xattr_user_set(const struct xattr_handler *handler, | |||
7412 | { | 7399 | { |
7413 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); | 7400 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); |
7414 | 7401 | ||
7415 | if (strcmp(name, "") == 0) | ||
7416 | return -EINVAL; | ||
7417 | if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) | 7402 | if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) |
7418 | return -EOPNOTSUPP; | 7403 | return -EOPNOTSUPP; |
7419 | 7404 | ||
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 571465d6df58..17efd76978c8 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -769,8 +769,6 @@ posix_acl_xattr_get(const struct xattr_handler *handler, | |||
769 | struct posix_acl *acl; | 769 | struct posix_acl *acl; |
770 | int error; | 770 | int error; |
771 | 771 | ||
772 | if (strcmp(name, "") != 0) | ||
773 | return -EINVAL; | ||
774 | if (!IS_POSIXACL(d_backing_inode(dentry))) | 772 | if (!IS_POSIXACL(d_backing_inode(dentry))) |
775 | return -EOPNOTSUPP; | 773 | return -EOPNOTSUPP; |
776 | if (d_is_symlink(dentry)) | 774 | if (d_is_symlink(dentry)) |
@@ -797,8 +795,6 @@ posix_acl_xattr_set(const struct xattr_handler *handler, | |||
797 | struct posix_acl *acl = NULL; | 795 | struct posix_acl *acl = NULL; |
798 | int ret; | 796 | int ret; |
799 | 797 | ||
800 | if (strcmp(name, "") != 0) | ||
801 | return -EINVAL; | ||
802 | if (!IS_POSIXACL(inode)) | 798 | if (!IS_POSIXACL(inode)) |
803 | return -EOPNOTSUPP; | 799 | return -EOPNOTSUPP; |
804 | if (!inode->i_op->set_acl) | 800 | if (!inode->i_op->set_acl) |
@@ -832,7 +828,7 @@ posix_acl_xattr_list(const struct xattr_handler *handler, | |||
832 | struct dentry *dentry, char *list, size_t list_size, | 828 | struct dentry *dentry, char *list, size_t list_size, |
833 | const char *name, size_t name_len) | 829 | const char *name, size_t name_len) |
834 | { | 830 | { |
835 | const char *xname = handler->prefix; | 831 | const char *xname = handler->name; |
836 | size_t size; | 832 | size_t size; |
837 | 833 | ||
838 | if (!IS_POSIXACL(d_backing_inode(dentry))) | 834 | if (!IS_POSIXACL(d_backing_inode(dentry))) |
@@ -845,7 +841,7 @@ posix_acl_xattr_list(const struct xattr_handler *handler, | |||
845 | } | 841 | } |
846 | 842 | ||
847 | const struct xattr_handler posix_acl_access_xattr_handler = { | 843 | const struct xattr_handler posix_acl_access_xattr_handler = { |
848 | .prefix = XATTR_NAME_POSIX_ACL_ACCESS, | 844 | .name = XATTR_NAME_POSIX_ACL_ACCESS, |
849 | .flags = ACL_TYPE_ACCESS, | 845 | .flags = ACL_TYPE_ACCESS, |
850 | .list = posix_acl_xattr_list, | 846 | .list = posix_acl_xattr_list, |
851 | .get = posix_acl_xattr_get, | 847 | .get = posix_acl_xattr_get, |
@@ -854,7 +850,7 @@ const struct xattr_handler posix_acl_access_xattr_handler = { | |||
854 | EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler); | 850 | EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler); |
855 | 851 | ||
856 | const struct xattr_handler posix_acl_default_xattr_handler = { | 852 | const struct xattr_handler posix_acl_default_xattr_handler = { |
857 | .prefix = XATTR_NAME_POSIX_ACL_DEFAULT, | 853 | .name = XATTR_NAME_POSIX_ACL_DEFAULT, |
858 | .flags = ACL_TYPE_DEFAULT, | 854 | .flags = ACL_TYPE_DEFAULT, |
859 | .list = posix_acl_xattr_list, | 855 | .list = posix_acl_xattr_list, |
860 | .get = posix_acl_xattr_get, | 856 | .get = posix_acl_xattr_get, |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 66b26fdfff8d..efe2ed3c13c5 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -756,7 +756,8 @@ find_xattr_handler_prefix(const struct xattr_handler **handlers, | |||
756 | return NULL; | 756 | return NULL; |
757 | 757 | ||
758 | for_each_xattr_handler(handlers, xah) { | 758 | for_each_xattr_handler(handlers, xah) { |
759 | if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0) | 759 | const char *prefix = xattr_prefix(xah); |
760 | if (strncmp(prefix, name, strlen(prefix)) == 0) | ||
760 | break; | 761 | break; |
761 | } | 762 | } |
762 | 763 | ||
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index 6a4cc344085c..2f0ccbaa2d92 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c | |||
@@ -228,9 +228,6 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, | |||
228 | struct dentry *d, const char *name, | 228 | struct dentry *d, const char *name, |
229 | void *buffer, size_t size) | 229 | void *buffer, size_t size) |
230 | { | 230 | { |
231 | if (name[0] == '\0') | ||
232 | return -EINVAL; | ||
233 | |||
234 | return squashfs_xattr_get(d_inode(d), handler->flags, name, | 231 | return squashfs_xattr_get(d_inode(d), handler->flags, name, |
235 | buffer, size); | 232 | buffer, size); |
236 | } | 233 | } |
diff --git a/fs/xattr.c b/fs/xattr.c index 58bdabcc9d35..418ad691cf4e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -681,13 +681,20 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name) | |||
681 | return NULL; | 681 | return NULL; |
682 | 682 | ||
683 | for_each_xattr_handler(handlers, handler) { | 683 | for_each_xattr_handler(handlers, handler) { |
684 | const char *n = strcmp_prefix(*name, handler->prefix); | 684 | const char *n; |
685 | |||
686 | n = strcmp_prefix(*name, xattr_prefix(handler)); | ||
685 | if (n) { | 687 | if (n) { |
688 | if (!handler->prefix ^ !*n) { | ||
689 | if (*n) | ||
690 | continue; | ||
691 | return ERR_PTR(-EINVAL); | ||
692 | } | ||
686 | *name = n; | 693 | *name = n; |
687 | break; | 694 | return handler; |
688 | } | 695 | } |
689 | } | 696 | } |
690 | return handler; | 697 | return ERR_PTR(-EOPNOTSUPP); |
691 | } | 698 | } |
692 | 699 | ||
693 | /* | 700 | /* |
@@ -699,8 +706,8 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s | |||
699 | const struct xattr_handler *handler; | 706 | const struct xattr_handler *handler; |
700 | 707 | ||
701 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 708 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
702 | if (!handler) | 709 | if (IS_ERR(handler)) |
703 | return -EOPNOTSUPP; | 710 | return PTR_ERR(handler); |
704 | return handler->get(handler, dentry, name, buffer, size); | 711 | return handler->get(handler, dentry, name, buffer, size); |
705 | } | 712 | } |
706 | 713 | ||
@@ -746,8 +753,8 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz | |||
746 | if (size == 0) | 753 | if (size == 0) |
747 | value = ""; /* empty EA, do not remove */ | 754 | value = ""; /* empty EA, do not remove */ |
748 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 755 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
749 | if (!handler) | 756 | if (IS_ERR(handler)) |
750 | return -EOPNOTSUPP; | 757 | return PTR_ERR(handler); |
751 | return handler->set(handler, dentry, name, value, size, flags); | 758 | return handler->set(handler, dentry, name, value, size, flags); |
752 | } | 759 | } |
753 | 760 | ||
@@ -761,8 +768,8 @@ generic_removexattr(struct dentry *dentry, const char *name) | |||
761 | const struct xattr_handler *handler; | 768 | const struct xattr_handler *handler; |
762 | 769 | ||
763 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 770 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
764 | if (!handler) | 771 | if (IS_ERR(handler)) |
765 | return -EOPNOTSUPP; | 772 | return PTR_ERR(handler); |
766 | return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE); | 773 | return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE); |
767 | } | 774 | } |
768 | 775 | ||
@@ -789,7 +796,7 @@ EXPORT_SYMBOL(generic_removexattr); | |||
789 | const char *xattr_full_name(const struct xattr_handler *handler, | 796 | const char *xattr_full_name(const struct xattr_handler *handler, |
790 | const char *name) | 797 | const char *name) |
791 | { | 798 | { |
792 | size_t prefix_len = strlen(handler->prefix); | 799 | size_t prefix_len = strlen(xattr_prefix(handler)); |
793 | 800 | ||
794 | return name - prefix_len; | 801 | return name - prefix_len; |
795 | } | 802 | } |
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 7288795718c9..36a43851aac0 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c | |||
@@ -39,9 +39,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, | |||
39 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 39 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
40 | int error, asize = size; | 40 | int error, asize = size; |
41 | 41 | ||
42 | if (strcmp(name, "") == 0) | ||
43 | return -EINVAL; | ||
44 | |||
45 | /* Convert Linux syscall to XFS internal ATTR flags */ | 42 | /* Convert Linux syscall to XFS internal ATTR flags */ |
46 | if (!size) { | 43 | if (!size) { |
47 | xflags |= ATTR_KERNOVAL; | 44 | xflags |= ATTR_KERNOVAL; |
@@ -84,9 +81,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, | |||
84 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 81 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
85 | int error; | 82 | int error; |
86 | 83 | ||
87 | if (strcmp(name, "") == 0) | ||
88 | return -EINVAL; | ||
89 | |||
90 | /* Convert Linux syscall to XFS internal ATTR flags */ | 84 | /* Convert Linux syscall to XFS internal ATTR flags */ |
91 | if (flags & XATTR_CREATE) | 85 | if (flags & XATTR_CREATE) |
92 | xflags |= ATTR_CREATE; | 86 | xflags |= ATTR_CREATE; |
diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 45fa3456a0cc..03c847fb6cc1 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h | |||
@@ -19,7 +19,13 @@ | |||
19 | struct inode; | 19 | struct inode; |
20 | struct dentry; | 20 | struct dentry; |
21 | 21 | ||
22 | /* | ||
23 | * struct xattr_handler: When @name is set, match attributes with exactly that | ||
24 | * name. When @prefix is set instead, match attributes with that prefix and | ||
25 | * with a non-empty suffix. | ||
26 | */ | ||
22 | struct xattr_handler { | 27 | struct xattr_handler { |
28 | const char *name; | ||
23 | const char *prefix; | 29 | const char *prefix; |
24 | int flags; /* fs private flags */ | 30 | int flags; /* fs private flags */ |
25 | size_t (*list)(const struct xattr_handler *, struct dentry *dentry, | 31 | size_t (*list)(const struct xattr_handler *, struct dentry *dentry, |
@@ -54,6 +60,11 @@ int generic_removexattr(struct dentry *dentry, const char *name); | |||
54 | ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name, | 60 | ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name, |
55 | char **xattr_value, size_t size, gfp_t flags); | 61 | char **xattr_value, size_t size, gfp_t flags); |
56 | 62 | ||
63 | static inline const char *xattr_prefix(const struct xattr_handler *handler) | ||
64 | { | ||
65 | return handler->prefix ?: handler->name; | ||
66 | } | ||
67 | |||
57 | struct simple_xattrs { | 68 | struct simple_xattrs { |
58 | struct list_head head; | 69 | struct list_head head; |
59 | spinlock_t lock; | 70 | spinlock_t lock; |