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