aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/xattr.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2015-03-25 14:26:41 -0400
committerChris Mason <clm@fb.com>2015-03-26 21:10:24 -0400
commit3c3b04d10ff1811a27f86684ccd2f5ba6983211d (patch)
tree3ad3d87edc735b1f2445fe92e9d5610ea367af32 /fs/btrfs/xattr.c
parentdcc82f4783ad91d4ab654f89f37ae9291cdc846a (diff)
btrfs: don't accept bare namespace as a valid xattr
Due to insufficient check in btrfs_is_valid_xattr, this unexpectedly works: $ touch file $ setfattr -n user. -v 1 file $ getfattr -d file user.="1" ie. the missing attribute name after the namespace. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=94291 Reported-by: William Douglas <william.douglas@intel.com> CC: <stable@vger.kernel.org> # 2.6.29+ Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r--fs/btrfs/xattr.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 883b93623bc5..45ea704be030 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -364,22 +364,42 @@ const struct xattr_handler *btrfs_xattr_handlers[] = {
364/* 364/*
365 * Check if the attribute is in a supported namespace. 365 * Check if the attribute is in a supported namespace.
366 * 366 *
367 * This applied after the check for the synthetic attributes in the system 367 * This is applied after the check for the synthetic attributes in the system
368 * namespace. 368 * namespace.
369 */ 369 */
370static bool btrfs_is_valid_xattr(const char *name) 370static int btrfs_is_valid_xattr(const char *name)
371{ 371{
372 return !strncmp(name, XATTR_SECURITY_PREFIX, 372 int len = strlen(name);
373 XATTR_SECURITY_PREFIX_LEN) || 373 int prefixlen = 0;
374 !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) || 374
375 !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || 375 if (!strncmp(name, XATTR_SECURITY_PREFIX,
376 !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) || 376 XATTR_SECURITY_PREFIX_LEN))
377 !strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN); 377 prefixlen = XATTR_SECURITY_PREFIX_LEN;
378 else if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
379 prefixlen = XATTR_SYSTEM_PREFIX_LEN;
380 else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
381 prefixlen = XATTR_TRUSTED_PREFIX_LEN;
382 else if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
383 prefixlen = XATTR_USER_PREFIX_LEN;
384 else if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
385 prefixlen = XATTR_BTRFS_PREFIX_LEN;
386 else
387 return -EOPNOTSUPP;
388
389 /*
390 * The name cannot consist of just prefix
391 */
392 if (len <= prefixlen)
393 return -EINVAL;
394
395 return 0;
378} 396}
379 397
380ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, 398ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
381 void *buffer, size_t size) 399 void *buffer, size_t size)
382{ 400{
401 int ret;
402
383 /* 403 /*
384 * If this is a request for a synthetic attribute in the system.* 404 * If this is a request for a synthetic attribute in the system.*
385 * namespace use the generic infrastructure to resolve a handler 405 * namespace use the generic infrastructure to resolve a handler
@@ -388,8 +408,9 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
388 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 408 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
389 return generic_getxattr(dentry, name, buffer, size); 409 return generic_getxattr(dentry, name, buffer, size);
390 410
391 if (!btrfs_is_valid_xattr(name)) 411 ret = btrfs_is_valid_xattr(name);
392 return -EOPNOTSUPP; 412 if (ret)
413 return ret;
393 return __btrfs_getxattr(dentry->d_inode, name, buffer, size); 414 return __btrfs_getxattr(dentry->d_inode, name, buffer, size);
394} 415}
395 416
@@ -397,6 +418,7 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
397 size_t size, int flags) 418 size_t size, int flags)
398{ 419{
399 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; 420 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
421 int ret;
400 422
401 /* 423 /*
402 * The permission on security.* and system.* is not checked 424 * The permission on security.* and system.* is not checked
@@ -413,8 +435,9 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
413 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 435 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
414 return generic_setxattr(dentry, name, value, size, flags); 436 return generic_setxattr(dentry, name, value, size, flags);
415 437
416 if (!btrfs_is_valid_xattr(name)) 438 ret = btrfs_is_valid_xattr(name);
417 return -EOPNOTSUPP; 439 if (ret)
440 return ret;
418 441
419 if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN)) 442 if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
420 return btrfs_set_prop(dentry->d_inode, name, 443 return btrfs_set_prop(dentry->d_inode, name,
@@ -430,6 +453,7 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
430int btrfs_removexattr(struct dentry *dentry, const char *name) 453int btrfs_removexattr(struct dentry *dentry, const char *name)
431{ 454{
432 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; 455 struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
456 int ret;
433 457
434 /* 458 /*
435 * The permission on security.* and system.* is not checked 459 * The permission on security.* and system.* is not checked
@@ -446,8 +470,9 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
446 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 470 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
447 return generic_removexattr(dentry, name); 471 return generic_removexattr(dentry, name);
448 472
449 if (!btrfs_is_valid_xattr(name)) 473 ret = btrfs_is_valid_xattr(name);
450 return -EOPNOTSUPP; 474 if (ret)
475 return ret;
451 476
452 if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN)) 477 if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
453 return btrfs_set_prop(dentry->d_inode, name, 478 return btrfs_set_prop(dentry->d_inode, name,