1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) 2001 Clemson University and The University of Chicago 4 * Copyright 2018 Omnibond Systems, L.L.C. 5 * 6 * See COPYING in top-level directory. 7 */ 8 9 /* 10 * Linux VFS extended attribute operations. 11 */ 12 13 #include "protocol.h" 14 #include "orangefs-kernel.h" 15 #include "orangefs-bufmap.h" 16 #include <linux/posix_acl_xattr.h> 17 #include <linux/xattr.h> 18 #include <linux/hashtable.h> 19 20 #define SYSTEM_ORANGEFS_KEY "system.pvfs2." 21 #define SYSTEM_ORANGEFS_KEY_LEN 13 22 23 /* 24 * this function returns 25 * 0 if the key corresponding to name is not meant to be printed as part 26 * of a listxattr. 27 * 1 if the key corresponding to name is meant to be returned as part of 28 * a listxattr. 29 * The ones that start SYSTEM_ORANGEFS_KEY are the ones to avoid printing. 30 */ 31 static int is_reserved_key(const char *key, size_t size) 32 { 33 34 if (size < SYSTEM_ORANGEFS_KEY_LEN) 35 return 1; 36 37 return strncmp(key, SYSTEM_ORANGEFS_KEY, SYSTEM_ORANGEFS_KEY_LEN) ? 1 : 0; 38 } 39 40 static inline int convert_to_internal_xattr_flags(int setxattr_flags) 41 { 42 int internal_flag = 0; 43 44 if (setxattr_flags & XATTR_REPLACE) { 45 /* Attribute must exist! */ 46 internal_flag = ORANGEFS_XATTR_REPLACE; 47 } else if (setxattr_flags & XATTR_CREATE) { 48 /* Attribute must not exist */ 49 internal_flag = ORANGEFS_XATTR_CREATE; 50 } 51 return internal_flag; 52 } 53 54 static unsigned int xattr_key(const char *key) 55 { 56 unsigned int i = 0; 57 if (!key) 58 return 0; 59 while (*key) 60 i += *key++; 61 return i % 16; 62 } 63 64 static struct orangefs_cached_xattr *find_cached_xattr(struct inode *inode, 65 const char *key) 66 { 67 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 68 struct orangefs_cached_xattr *cx; 69 struct hlist_head *h; 70 struct hlist_node *tmp; 71 h = &orangefs_inode->xattr_cache[xattr_key(key)]; 72 if (hlist_empty(h)) 73 return NULL; 74 hlist_for_each_entry_safe(cx, tmp, h, node) { 75 /* if (!time_before(jiffies, cx->timeout)) { 76 hlist_del(&cx->node); 77 kfree(cx); 78 continue; 79 }*/ 80 if (!strcmp(cx->key, key)) 81 return cx; 82 } 83 return NULL; 84 } 85 86 /* 87 * Tries to get a specified key's attributes of a given 88 * file into a user-specified buffer. Note that the getxattr 89 * interface allows for the users to probe the size of an 90 * extended attribute by passing in a value of 0 to size. 91 * Thus our return value is always the size of the attribute 92 * unless the key does not exist for the file and/or if 93 * there were errors in fetching the attribute value. 94 */ 95 ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, 96 void *buffer, size_t size) 97 { 98 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 99 struct orangefs_kernel_op_s *new_op = NULL; 100 struct orangefs_cached_xattr *cx; 101 ssize_t ret = -ENOMEM; 102 ssize_t length = 0; 103 int fsuid; 104 int fsgid; 105 106 gossip_debug(GOSSIP_XATTR_DEBUG, 107 "%s: name %s, buffer_size %zd\n", 108 __func__, name, size); 109 110 if (S_ISLNK(inode->i_mode)) 111 return -EOPNOTSUPP; 112 113 if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) 114 return -EINVAL; 115 116 fsuid = from_kuid(&init_user_ns, current_fsuid()); 117 fsgid = from_kgid(&init_user_ns, current_fsgid()); 118 119 gossip_debug(GOSSIP_XATTR_DEBUG, 120 "getxattr on inode %pU, name %s " 121 "(uid %o, gid %o)\n", 122 get_khandle_from_ino(inode), 123 name, 124 fsuid, 125 fsgid); 126 127 down_read(&orangefs_inode->xattr_sem); 128 129 cx = find_cached_xattr(inode, name); 130 if (cx && time_before(jiffies, cx->timeout)) { 131 if (cx->length == -1) { 132 ret = -ENODATA; 133 goto out_unlock; 134 } else { 135 if (size == 0) { 136 ret = cx->length; 137 goto out_unlock; 138 } 139 if (cx->length > size) { 140 ret = -ERANGE; 141 goto out_unlock; 142 } 143 memcpy(buffer, cx->val, cx->length); 144 memset(buffer + cx->length, 0, size - cx->length); 145 ret = cx->length; 146 goto out_unlock; 147 } 148 } 149 150 new_op = op_alloc(ORANGEFS_VFS_OP_GETXATTR); 151 if (!new_op) 152 goto out_unlock; 153 154 new_op->upcall.req.getxattr.refn = orangefs_inode->refn; 155 strcpy(new_op->upcall.req.getxattr.key, name); 156 157 /* 158 * NOTE: Although keys are meant to be NULL terminated textual 159 * strings, I am going to explicitly pass the length just in case 160 * we change this later on... 161 */ 162 new_op->upcall.req.getxattr.key_sz = strlen(name) + 1; 163 164 ret = service_operation(new_op, "orangefs_inode_getxattr", 165 get_interruptible_flag(inode)); 166 if (ret != 0) { 167 if (ret == -ENOENT) { 168 ret = -ENODATA; 169 gossip_debug(GOSSIP_XATTR_DEBUG, 170 "orangefs_inode_getxattr: inode %pU key %s" 171 " does not exist!\n", 172 get_khandle_from_ino(inode), 173 (char *)new_op->upcall.req.getxattr.key); 174 cx = kmalloc(sizeof *cx, GFP_KERNEL); 175 if (cx) { 176 strcpy(cx->key, name); 177 cx->length = -1; 178 cx->timeout = jiffies + 179 orangefs_getattr_timeout_msecs*HZ/1000; 180 hlist_add_head( &cx->node, 181 &orangefs_inode->xattr_cache[xattr_key(cx->key)]); 182 } 183 } 184 goto out_release_op; 185 } 186 187 /* 188 * Length returned includes null terminator. 189 */ 190 length = new_op->downcall.resp.getxattr.val_sz; 191 192 /* 193 * Just return the length of the queried attribute. 194 */ 195 if (size == 0) { 196 ret = length; 197 goto out_release_op; 198 } 199 200 /* 201 * Check to see if key length is > provided buffer size. 202 */ 203 if (length > size) { 204 ret = -ERANGE; 205 goto out_release_op; 206 } 207 208 memcpy(buffer, new_op->downcall.resp.getxattr.val, length); 209 memset(buffer + length, 0, size - length); 210 gossip_debug(GOSSIP_XATTR_DEBUG, 211 "orangefs_inode_getxattr: inode %pU " 212 "key %s key_sz %d, val_len %d\n", 213 get_khandle_from_ino(inode), 214 (char *)new_op-> 215 upcall.req.getxattr.key, 216 (int)new_op-> 217 upcall.req.getxattr.key_sz, 218 (int)ret); 219 220 ret = length; 221 222 if (cx) { 223 strcpy(cx->key, name); 224 memcpy(cx->val, buffer, length); 225 cx->length = length; 226 cx->timeout = jiffies + HZ; 227 } else { 228 cx = kmalloc(sizeof *cx, GFP_KERNEL); 229 if (cx) { 230 strcpy(cx->key, name); 231 memcpy(cx->val, buffer, length); 232 cx->length = length; 233 cx->timeout = jiffies + HZ; 234 hlist_add_head(&cx->node, 235 &orangefs_inode->xattr_cache[xattr_key(cx->key)]); 236 } 237 } 238 239 out_release_op: 240 op_release(new_op); 241 out_unlock: 242 up_read(&orangefs_inode->xattr_sem); 243 return ret; 244 } 245 246 static int orangefs_inode_removexattr(struct inode *inode, const char *name, 247 int flags) 248 { 249 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 250 struct orangefs_kernel_op_s *new_op = NULL; 251 struct orangefs_cached_xattr *cx; 252 struct hlist_head *h; 253 struct hlist_node *tmp; 254 int ret = -ENOMEM; 255 256 if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) 257 return -EINVAL; 258 259 down_write(&orangefs_inode->xattr_sem); 260 new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR); 261 if (!new_op) 262 goto out_unlock; 263 264 new_op->upcall.req.removexattr.refn = orangefs_inode->refn; 265 /* 266 * NOTE: Although keys are meant to be NULL terminated 267 * textual strings, I am going to explicitly pass the 268 * length just in case we change this later on... 269 */ 270 strcpy(new_op->upcall.req.removexattr.key, name); 271 new_op->upcall.req.removexattr.key_sz = strlen(name) + 1; 272 273 gossip_debug(GOSSIP_XATTR_DEBUG, 274 "orangefs_inode_removexattr: key %s, key_sz %d\n", 275 (char *)new_op->upcall.req.removexattr.key, 276 (int)new_op->upcall.req.removexattr.key_sz); 277 278 ret = service_operation(new_op, 279 "orangefs_inode_removexattr", 280 get_interruptible_flag(inode)); 281 if (ret == -ENOENT) { 282 /* 283 * Request to replace a non-existent attribute is an error. 284 */ 285 if (flags & XATTR_REPLACE) 286 ret = -ENODATA; 287 else 288 ret = 0; 289 } 290 291 gossip_debug(GOSSIP_XATTR_DEBUG, 292 "orangefs_inode_removexattr: returning %d\n", ret); 293 294 op_release(new_op); 295 296 h = &orangefs_inode->xattr_cache[xattr_key(name)]; 297 hlist_for_each_entry_safe(cx, tmp, h, node) { 298 if (!strcmp(cx->key, name)) { 299 hlist_del(&cx->node); 300 kfree(cx); 301 break; 302 } 303 } 304 305 out_unlock: 306 up_write(&orangefs_inode->xattr_sem); 307 return ret; 308 } 309 310 /* 311 * Tries to set an attribute for a given key on a file. 312 * 313 * Returns a -ve number on error and 0 on success. Key is text, but value 314 * can be binary! 315 */ 316 int orangefs_inode_setxattr(struct inode *inode, const char *name, 317 const void *value, size_t size, int flags) 318 { 319 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 320 struct orangefs_kernel_op_s *new_op; 321 int internal_flag = 0; 322 struct orangefs_cached_xattr *cx; 323 struct hlist_head *h; 324 struct hlist_node *tmp; 325 int ret = -ENOMEM; 326 327 gossip_debug(GOSSIP_XATTR_DEBUG, 328 "%s: name %s, buffer_size %zd\n", 329 __func__, name, size); 330 331 if (size > ORANGEFS_MAX_XATTR_VALUELEN) 332 return -EINVAL; 333 if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) 334 return -EINVAL; 335 336 internal_flag = convert_to_internal_xattr_flags(flags); 337 338 /* This is equivalent to a removexattr */ 339 if (size == 0 && !value) { 340 gossip_debug(GOSSIP_XATTR_DEBUG, 341 "removing xattr (%s)\n", 342 name); 343 return orangefs_inode_removexattr(inode, name, flags); 344 } 345 346 gossip_debug(GOSSIP_XATTR_DEBUG, 347 "setxattr on inode %pU, name %s\n", 348 get_khandle_from_ino(inode), 349 name); 350 351 down_write(&orangefs_inode->xattr_sem); 352 new_op = op_alloc(ORANGEFS_VFS_OP_SETXATTR); 353 if (!new_op) 354 goto out_unlock; 355 356 357 new_op->upcall.req.setxattr.refn = orangefs_inode->refn; 358 new_op->upcall.req.setxattr.flags = internal_flag; 359 /* 360 * NOTE: Although keys are meant to be NULL terminated textual 361 * strings, I am going to explicitly pass the length just in 362 * case we change this later on... 363 */ 364 strcpy(new_op->upcall.req.setxattr.keyval.key, name); 365 new_op->upcall.req.setxattr.keyval.key_sz = strlen(name) + 1; 366 memcpy(new_op->upcall.req.setxattr.keyval.val, value, size); 367 new_op->upcall.req.setxattr.keyval.val_sz = size; 368 369 gossip_debug(GOSSIP_XATTR_DEBUG, 370 "orangefs_inode_setxattr: key %s, key_sz %d " 371 " value size %zd\n", 372 (char *)new_op->upcall.req.setxattr.keyval.key, 373 (int)new_op->upcall.req.setxattr.keyval.key_sz, 374 size); 375 376 ret = service_operation(new_op, 377 "orangefs_inode_setxattr", 378 get_interruptible_flag(inode)); 379 380 gossip_debug(GOSSIP_XATTR_DEBUG, 381 "orangefs_inode_setxattr: returning %d\n", 382 ret); 383 384 /* when request is serviced properly, free req op struct */ 385 op_release(new_op); 386 387 h = &orangefs_inode->xattr_cache[xattr_key(name)]; 388 hlist_for_each_entry_safe(cx, tmp, h, node) { 389 if (!strcmp(cx->key, name)) { 390 hlist_del(&cx->node); 391 kfree(cx); 392 break; 393 } 394 } 395 396 out_unlock: 397 up_write(&orangefs_inode->xattr_sem); 398 return ret; 399 } 400 401 /* 402 * Tries to get a specified object's keys into a user-specified buffer of a 403 * given size. Note that like the previous instances of xattr routines, this 404 * also allows you to pass in a NULL pointer and 0 size to probe the size for 405 * subsequent memory allocations. Thus our return value is always the size of 406 * all the keys unless there were errors in fetching the keys! 407 */ 408 ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) 409 { 410 struct inode *inode = dentry->d_inode; 411 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 412 struct orangefs_kernel_op_s *new_op; 413 __u64 token = ORANGEFS_ITERATE_START; 414 ssize_t ret = -ENOMEM; 415 ssize_t total = 0; 416 int count_keys = 0; 417 int key_size; 418 int i = 0; 419 int returned_count = 0; 420 421 if (size > 0 && !buffer) { 422 gossip_err("%s: bogus NULL pointers\n", __func__); 423 return -EINVAL; 424 } 425 426 down_read(&orangefs_inode->xattr_sem); 427 new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR); 428 if (!new_op) 429 goto out_unlock; 430 431 if (buffer && size > 0) 432 memset(buffer, 0, size); 433 434 try_again: 435 key_size = 0; 436 new_op->upcall.req.listxattr.refn = orangefs_inode->refn; 437 new_op->upcall.req.listxattr.token = token; 438 new_op->upcall.req.listxattr.requested_count = 439 (size == 0) ? 0 : ORANGEFS_MAX_XATTR_LISTLEN; 440 ret = service_operation(new_op, __func__, 441 get_interruptible_flag(inode)); 442 if (ret != 0) 443 goto done; 444 445 if (size == 0) { 446 /* 447 * This is a bit of a big upper limit, but I did not want to 448 * spend too much time getting this correct, since users end 449 * up allocating memory rather than us... 450 */ 451 total = new_op->downcall.resp.listxattr.returned_count * 452 ORANGEFS_MAX_XATTR_NAMELEN; 453 goto done; 454 } 455 456 returned_count = new_op->downcall.resp.listxattr.returned_count; 457 if (returned_count < 0 || 458 returned_count > ORANGEFS_MAX_XATTR_LISTLEN) { 459 gossip_err("%s: impossible value for returned_count:%d:\n", 460 __func__, 461 returned_count); 462 ret = -EIO; 463 goto done; 464 } 465 466 /* 467 * Check to see how much can be fit in the buffer. Fit only whole keys. 468 */ 469 for (i = 0; i < returned_count; i++) { 470 if (new_op->downcall.resp.listxattr.lengths[i] < 0 || 471 new_op->downcall.resp.listxattr.lengths[i] > 472 ORANGEFS_MAX_XATTR_NAMELEN) { 473 gossip_err("%s: impossible value for lengths[%d]\n", 474 __func__, 475 new_op->downcall.resp.listxattr.lengths[i]); 476 ret = -EIO; 477 goto done; 478 } 479 if (total + new_op->downcall.resp.listxattr.lengths[i] > size) 480 goto done; 481 482 /* 483 * Since many dumb programs try to setxattr() on our reserved 484 * xattrs this is a feeble attempt at defeating those by not 485 * listing them in the output of listxattr.. sigh 486 */ 487 if (is_reserved_key(new_op->downcall.resp.listxattr.key + 488 key_size, 489 new_op->downcall.resp. 490 listxattr.lengths[i])) { 491 gossip_debug(GOSSIP_XATTR_DEBUG, "Copying key %d -> %s\n", 492 i, new_op->downcall.resp.listxattr.key + 493 key_size); 494 memcpy(buffer + total, 495 new_op->downcall.resp.listxattr.key + key_size, 496 new_op->downcall.resp.listxattr.lengths[i]); 497 total += new_op->downcall.resp.listxattr.lengths[i]; 498 count_keys++; 499 } else { 500 gossip_debug(GOSSIP_XATTR_DEBUG, "[RESERVED] key %d -> %s\n", 501 i, new_op->downcall.resp.listxattr.key + 502 key_size); 503 } 504 key_size += new_op->downcall.resp.listxattr.lengths[i]; 505 } 506 507 /* 508 * Since the buffer was large enough, we might have to continue 509 * fetching more keys! 510 */ 511 token = new_op->downcall.resp.listxattr.token; 512 if (token != ORANGEFS_ITERATE_END) 513 goto try_again; 514 515 done: 516 gossip_debug(GOSSIP_XATTR_DEBUG, "%s: returning %d" 517 " [size of buffer %ld] (filled in %d keys)\n", 518 __func__, 519 ret ? (int)ret : (int)total, 520 (long)size, 521 count_keys); 522 op_release(new_op); 523 if (ret == 0) 524 ret = total; 525 out_unlock: 526 up_read(&orangefs_inode->xattr_sem); 527 return ret; 528 } 529 530 static int orangefs_xattr_set_default(const struct xattr_handler *handler, 531 struct mnt_idmap *idmap, 532 struct dentry *unused, 533 struct inode *inode, 534 const char *name, 535 const void *buffer, 536 size_t size, 537 int flags) 538 { 539 return orangefs_inode_setxattr(inode, name, buffer, size, flags); 540 } 541 542 static int orangefs_xattr_get_default(const struct xattr_handler *handler, 543 struct dentry *unused, 544 struct inode *inode, 545 const char *name, 546 void *buffer, 547 size_t size) 548 { 549 return orangefs_inode_getxattr(inode, name, buffer, size); 550 551 } 552 553 static const struct xattr_handler orangefs_xattr_default_handler = { 554 .prefix = "", /* match any name => handlers called with full name */ 555 .get = orangefs_xattr_get_default, 556 .set = orangefs_xattr_set_default, 557 }; 558 559 const struct xattr_handler * const orangefs_xattr_handlers[] = { 560 &orangefs_xattr_default_handler, 561 NULL 562 }; 563