Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-linus-4.8-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux

Pull orangefs updates from Mike Mashall:
"Orangefs cleanups and enablement of O_DIRECT in open.

Cleanups:

- remove some unused defines, and also some obfuscatory ones.

- remove a redundant xattr handler.

- Remove useless xattr prefix arguments.

- Be more picky about uid and gid handling WRT namespaces.

Our use of current_user_ns() instead of init_user_ns left open the
possibility that users could spoof their uids or gids when the
server was running in a different namespace in "default security"
mode.

- Allow open(2) to succeed with O_DIRECT"

* tag 'for-linus-4.8-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux:
orangefs: fix namespace handling
Orangefs: allow O_DIRECT in open
orangefs: Remove useless xattr prefix arguments
orangefs: Remove redundant "trusted." xattr handler
orangefs: Remove useless defines

+61 -146
+7 -10
fs/orangefs/acl.c
··· 18 18 19 19 switch (type) { 20 20 case ACL_TYPE_ACCESS: 21 - key = ORANGEFS_XATTR_NAME_ACL_ACCESS; 21 + key = XATTR_NAME_POSIX_ACL_ACCESS; 22 22 break; 23 23 case ACL_TYPE_DEFAULT: 24 - key = ORANGEFS_XATTR_NAME_ACL_DEFAULT; 24 + key = XATTR_NAME_POSIX_ACL_DEFAULT; 25 25 break; 26 26 default: 27 27 gossip_err("orangefs_get_acl: bogus value of type %d\n", type); ··· 43 43 get_khandle_from_ino(inode), 44 44 key, 45 45 type); 46 - ret = orangefs_inode_getxattr(inode, 47 - "", 48 - key, 49 - value, 50 - ORANGEFS_MAX_XATTR_VALUELEN); 46 + ret = orangefs_inode_getxattr(inode, key, value, 47 + ORANGEFS_MAX_XATTR_VALUELEN); 51 48 /* if the key exists, convert it to an in-memory rep */ 52 49 if (ret > 0) { 53 50 acl = posix_acl_from_xattr(&init_user_ns, value, ret); ··· 71 74 72 75 switch (type) { 73 76 case ACL_TYPE_ACCESS: 74 - name = ORANGEFS_XATTR_NAME_ACL_ACCESS; 77 + name = XATTR_NAME_POSIX_ACL_ACCESS; 75 78 if (acl) { 76 79 umode_t mode = inode->i_mode; 77 80 /* ··· 95 98 } 96 99 break; 97 100 case ACL_TYPE_DEFAULT: 98 - name = ORANGEFS_XATTR_NAME_ACL_DEFAULT; 101 + name = XATTR_NAME_POSIX_ACL_DEFAULT; 99 102 break; 100 103 default: 101 104 gossip_err("%s: invalid type %d!\n", __func__, type); ··· 128 131 * will xlate to a removexattr. However, we don't want removexattr 129 132 * complain if attributes does not exist. 130 133 */ 131 - error = orangefs_inode_setxattr(inode, "", name, value, size, 0); 134 + error = orangefs_inode_setxattr(inode, name, value, size, 0); 132 135 133 136 out: 134 137 kfree(value);
+7
fs/orangefs/devorangefs-req.c
··· 116 116 { 117 117 int ret = -EINVAL; 118 118 119 + /* in order to ensure that the filesystem driver sees correct UIDs */ 120 + if (file->f_cred->user_ns != &init_user_ns) { 121 + gossip_err("%s: device cannot be opened outside init_user_ns\n", 122 + __func__); 123 + goto out; 124 + } 125 + 119 126 if (!(file->f_flags & O_NONBLOCK)) { 120 127 gossip_err("%s: device cannot be opened in blocking mode\n", 121 128 __func__);
-2
fs/orangefs/file.c
··· 516 516 if (cmd == FS_IOC_GETFLAGS) { 517 517 val = 0; 518 518 ret = orangefs_inode_getxattr(file_inode(file), 519 - ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, 520 519 "user.pvfs2.meta_hint", 521 520 &val, sizeof(val)); 522 521 if (ret < 0 && ret != -ENODATA) ··· 548 549 "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n", 549 550 (unsigned long long)val); 550 551 ret = orangefs_inode_setxattr(file_inode(file), 551 - ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, 552 552 "user.pvfs2.meta_hint", 553 553 &val, sizeof(val), 0); 554 554 }
+11 -14
fs/orangefs/inode.c
··· 124 124 * will need to be able to use O_DIRECT on open in order to support 125 125 * AIO. Modeled after NFS, they do this too. 126 126 */ 127 - /* 128 - * static ssize_t orangefs_direct_IO(int rw, 129 - * struct kiocb *iocb, 130 - * struct iov_iter *iter, 131 - * loff_t offset) 132 - *{ 133 - * gossip_debug(GOSSIP_INODE_DEBUG, 134 - * "orangefs_direct_IO: %s\n", 135 - * iocb->ki_filp->f_path.dentry->d_name.name); 136 - * 137 - * return -EINVAL; 138 - *} 139 - */ 127 + 128 + static ssize_t orangefs_direct_IO(struct kiocb *iocb, 129 + struct iov_iter *iter) 130 + { 131 + gossip_debug(GOSSIP_INODE_DEBUG, 132 + "orangefs_direct_IO: %s\n", 133 + iocb->ki_filp->f_path.dentry->d_name.name); 134 + 135 + return -EINVAL; 136 + } 140 137 141 138 struct backing_dev_info orangefs_backing_dev_info = { 142 139 .name = "orangefs", ··· 147 150 .readpages = orangefs_readpages, 148 151 .invalidatepage = orangefs_invalidatepage, 149 152 .releasepage = orangefs_releasepage, 150 - /* .direct_IO = orangefs_direct_IO */ 153 + .direct_IO = orangefs_direct_IO, 151 154 }; 152 155 153 156 static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
+2 -2
fs/orangefs/orangefs-cache.c
··· 136 136 llu(new_op->tag), 137 137 get_opname_string(new_op)); 138 138 139 - new_op->upcall.uid = from_kuid(current_user_ns(), 139 + new_op->upcall.uid = from_kuid(&init_user_ns, 140 140 current_fsuid()); 141 141 142 - new_op->upcall.gid = from_kgid(current_user_ns(), 142 + new_op->upcall.gid = from_kgid(&init_user_ns, 143 143 current_fsgid()); 144 144 } else { 145 145 gossip_err("op_alloc: kmem_cache_zalloc failed!\n");
+2 -15
fs/orangefs/orangefs-kernel.h
··· 119 119 #define ORANGEFS_CACHE_CREATE_FLAGS 0 120 120 #endif /* ((defined ORANGEFS_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */ 121 121 122 - /* orangefs xattr and acl related defines */ 123 - #define ORANGEFS_XATTR_INDEX_POSIX_ACL_ACCESS 1 124 - #define ORANGEFS_XATTR_INDEX_POSIX_ACL_DEFAULT 2 125 - #define ORANGEFS_XATTR_INDEX_TRUSTED 3 126 - #define ORANGEFS_XATTR_INDEX_DEFAULT 4 127 - 128 - #define ORANGEFS_XATTR_NAME_ACL_ACCESS XATTR_NAME_POSIX_ACL_ACCESS 129 - #define ORANGEFS_XATTR_NAME_ACL_DEFAULT XATTR_NAME_POSIX_ACL_DEFAULT 130 - #define ORANGEFS_XATTR_NAME_TRUSTED_PREFIX "trusted." 131 - #define ORANGEFS_XATTR_NAME_DEFAULT_PREFIX "" 132 - 133 122 /* these functions are defined in orangefs-utils.c */ 134 123 int orangefs_prepare_cdm_array(char *debug_array_string); 135 124 int orangefs_prepare_debugfs_help_string(int); ··· 517 528 int orangefs_flush_inode(struct inode *inode); 518 529 519 530 ssize_t orangefs_inode_getxattr(struct inode *inode, 520 - const char *prefix, 521 531 const char *name, 522 532 void *buffer, 523 533 size_t size); 524 534 525 535 int orangefs_inode_setxattr(struct inode *inode, 526 - const char *prefix, 527 536 const char *name, 528 537 const void *value, 529 538 size_t size, ··· 587 600 588 601 #define fill_default_sys_attrs(sys_attr, type, mode) \ 589 602 do { \ 590 - sys_attr.owner = from_kuid(current_user_ns(), current_fsuid()); \ 591 - sys_attr.group = from_kgid(current_user_ns(), current_fsgid()); \ 603 + sys_attr.owner = from_kuid(&init_user_ns, current_fsuid()); \ 604 + sys_attr.group = from_kgid(&init_user_ns, current_fsgid()); \ 592 605 sys_attr.perms = ORANGEFS_util_translate_mode(mode); \ 593 606 sys_attr.mtime = 0; \ 594 607 sys_attr.atime = 0; \
+2 -2
fs/orangefs/orangefs-utils.c
··· 153 153 */ 154 154 attrs->mask = 0; 155 155 if (iattr->ia_valid & ATTR_UID) { 156 - attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid); 156 + attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid); 157 157 attrs->mask |= ORANGEFS_ATTR_SYS_UID; 158 158 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner); 159 159 } 160 160 if (iattr->ia_valid & ATTR_GID) { 161 - attrs->group = from_kgid(current_user_ns(), iattr->ia_gid); 161 + attrs->group = from_kgid(&init_user_ns, iattr->ia_gid); 162 162 attrs->mask |= ORANGEFS_ATTR_SYS_GID; 163 163 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group); 164 164 }
+30 -101
fs/orangefs/xattr.c
··· 59 59 * unless the key does not exist for the file and/or if 60 60 * there were errors in fetching the attribute value. 61 61 */ 62 - ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix, 63 - const char *name, void *buffer, size_t size) 62 + ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, 63 + void *buffer, size_t size) 64 64 { 65 65 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 66 66 struct orangefs_kernel_op_s *new_op = NULL; ··· 70 70 int fsgid; 71 71 72 72 gossip_debug(GOSSIP_XATTR_DEBUG, 73 - "%s: prefix %s name %s, buffer_size %zd\n", 74 - __func__, prefix, name, size); 73 + "%s: name %s, buffer_size %zd\n", 74 + __func__, name, size); 75 75 76 - if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) { 76 + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { 77 77 gossip_err("Invalid key length (%d)\n", 78 - (int)(strlen(name) + strlen(prefix))); 78 + (int)strlen(name)); 79 79 return -EINVAL; 80 80 } 81 81 82 - fsuid = from_kuid(current_user_ns(), current_fsuid()); 83 - fsgid = from_kgid(current_user_ns(), current_fsgid()); 82 + fsuid = from_kuid(&init_user_ns, current_fsuid()); 83 + fsgid = from_kgid(&init_user_ns, current_fsgid()); 84 84 85 85 gossip_debug(GOSSIP_XATTR_DEBUG, 86 86 "getxattr on inode %pU, name %s " ··· 97 97 goto out_unlock; 98 98 99 99 new_op->upcall.req.getxattr.refn = orangefs_inode->refn; 100 - ret = snprintf((char *)new_op->upcall.req.getxattr.key, 101 - ORANGEFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name); 100 + strcpy(new_op->upcall.req.getxattr.key, name); 102 101 103 102 /* 104 103 * NOTE: Although keys are meant to be NULL terminated textual 105 104 * strings, I am going to explicitly pass the length just in case 106 105 * we change this later on... 107 106 */ 108 - new_op->upcall.req.getxattr.key_sz = ret + 1; 107 + new_op->upcall.req.getxattr.key_sz = strlen(name) + 1; 109 108 110 109 ret = service_operation(new_op, "orangefs_inode_getxattr", 111 110 get_interruptible_flag(inode)); ··· 162 163 return ret; 163 164 } 164 165 165 - static int orangefs_inode_removexattr(struct inode *inode, 166 - const char *prefix, 167 - const char *name, 168 - int flags) 166 + static int orangefs_inode_removexattr(struct inode *inode, const char *name, 167 + int flags) 169 168 { 170 169 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 171 170 struct orangefs_kernel_op_s *new_op = NULL; ··· 180 183 * textual strings, I am going to explicitly pass the 181 184 * length just in case we change this later on... 182 185 */ 183 - ret = snprintf((char *)new_op->upcall.req.removexattr.key, 184 - ORANGEFS_MAX_XATTR_NAMELEN, 185 - "%s%s", 186 - (prefix ? prefix : ""), 187 - name); 188 - new_op->upcall.req.removexattr.key_sz = ret + 1; 186 + strcpy(new_op->upcall.req.removexattr.key, name); 187 + new_op->upcall.req.removexattr.key_sz = strlen(name) + 1; 189 188 190 189 gossip_debug(GOSSIP_XATTR_DEBUG, 191 190 "orangefs_inode_removexattr: key %s, key_sz %d\n", ··· 216 223 * Returns a -ve number on error and 0 on success. Key is text, but value 217 224 * can be binary! 218 225 */ 219 - int orangefs_inode_setxattr(struct inode *inode, const char *prefix, 220 - const char *name, const void *value, size_t size, int flags) 226 + int orangefs_inode_setxattr(struct inode *inode, const char *name, 227 + const void *value, size_t size, int flags) 221 228 { 222 229 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 223 230 struct orangefs_kernel_op_s *new_op; ··· 225 232 int ret = -ENOMEM; 226 233 227 234 gossip_debug(GOSSIP_XATTR_DEBUG, 228 - "%s: prefix %s, name %s, buffer_size %zd\n", 229 - __func__, prefix, name, size); 235 + "%s: name %s, buffer_size %zd\n", 236 + __func__, name, size); 230 237 231 238 if (size >= ORANGEFS_MAX_XATTR_VALUELEN || 232 239 flags < 0) { ··· 238 245 239 246 internal_flag = convert_to_internal_xattr_flags(flags); 240 247 241 - if (prefix) { 242 - if (strlen(name) + strlen(prefix) >= ORANGEFS_MAX_XATTR_NAMELEN) { 243 - gossip_err 244 - ("orangefs_inode_setxattr: bogus key size (%d)\n", 245 - (int)(strlen(name) + strlen(prefix))); 246 - return -EINVAL; 247 - } 248 - } else { 249 - if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { 250 - gossip_err 251 - ("orangefs_inode_setxattr: bogus key size (%d)\n", 252 - (int)(strlen(name))); 253 - return -EINVAL; 254 - } 248 + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { 249 + gossip_err 250 + ("orangefs_inode_setxattr: bogus key size (%d)\n", 251 + (int)(strlen(name))); 252 + return -EINVAL; 255 253 } 256 254 257 255 /* This is equivalent to a removexattr */ 258 256 if (size == 0 && value == NULL) { 259 257 gossip_debug(GOSSIP_XATTR_DEBUG, 260 - "removing xattr (%s%s)\n", 261 - prefix, 258 + "removing xattr (%s)\n", 262 259 name); 263 - return orangefs_inode_removexattr(inode, prefix, name, flags); 260 + return orangefs_inode_removexattr(inode, name, flags); 264 261 } 265 262 266 263 gossip_debug(GOSSIP_XATTR_DEBUG, ··· 271 288 * strings, I am going to explicitly pass the length just in 272 289 * case we change this later on... 273 290 */ 274 - ret = snprintf((char *)new_op->upcall.req.setxattr.keyval.key, 275 - ORANGEFS_MAX_XATTR_NAMELEN, 276 - "%s%s", 277 - prefix, name); 278 - new_op->upcall.req.setxattr.keyval.key_sz = ret + 1; 291 + strcpy(new_op->upcall.req.setxattr.keyval.key, name); 292 + new_op->upcall.req.setxattr.keyval.key_sz = strlen(name) + 1; 279 293 memcpy(new_op->upcall.req.setxattr.keyval.val, value, size); 280 294 new_op->upcall.req.setxattr.keyval.val_sz = size; 281 295 ··· 435 455 size_t size, 436 456 int flags) 437 457 { 438 - return orangefs_inode_setxattr(inode, 439 - ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, 440 - name, 441 - buffer, 442 - size, 443 - flags); 458 + return orangefs_inode_setxattr(inode, name, buffer, size, flags); 444 459 } 445 460 446 461 static int orangefs_xattr_get_default(const struct xattr_handler *handler, ··· 445 470 void *buffer, 446 471 size_t size) 447 472 { 448 - return orangefs_inode_getxattr(inode, 449 - ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, 450 - name, 451 - buffer, 452 - size); 473 + return orangefs_inode_getxattr(inode, name, buffer, size); 453 474 454 475 } 455 - 456 - static int orangefs_xattr_set_trusted(const struct xattr_handler *handler, 457 - struct dentry *unused, 458 - struct inode *inode, 459 - const char *name, 460 - const void *buffer, 461 - size_t size, 462 - int flags) 463 - { 464 - return orangefs_inode_setxattr(inode, 465 - ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, 466 - name, 467 - buffer, 468 - size, 469 - flags); 470 - } 471 - 472 - static int orangefs_xattr_get_trusted(const struct xattr_handler *handler, 473 - struct dentry *unused, 474 - struct inode *inode, 475 - const char *name, 476 - void *buffer, 477 - size_t size) 478 - { 479 - return orangefs_inode_getxattr(inode, 480 - ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, 481 - name, 482 - buffer, 483 - size); 484 - } 485 - 486 - static struct xattr_handler orangefs_xattr_trusted_handler = { 487 - .prefix = ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, 488 - .get = orangefs_xattr_get_trusted, 489 - .set = orangefs_xattr_set_trusted, 490 - }; 491 476 492 477 static struct xattr_handler orangefs_xattr_default_handler = { 493 - /* 494 - * NOTE: this is set to be the empty string. 495 - * so that all un-prefixed xattrs keys get caught 496 - * here! 497 - */ 498 - .prefix = ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, 478 + .prefix = "", /* match any name => handlers called with full name */ 499 479 .get = orangefs_xattr_get_default, 500 480 .set = orangefs_xattr_set_default, 501 481 }; ··· 458 528 const struct xattr_handler *orangefs_xattr_handlers[] = { 459 529 &posix_acl_access_xattr_handler, 460 530 &posix_acl_default_xattr_handler, 461 - &orangefs_xattr_trusted_handler, 462 531 &orangefs_xattr_default_handler, 463 532 NULL 464 533 };