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