1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * Copyright (c) 2022-2024 Oracle. 5 * All rights reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_shared.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_bmap_btree.h" 15 #include "xfs_inode.h" 16 #include "xfs_error.h" 17 #include "xfs_trace.h" 18 #include "xfs_trans.h" 19 #include "xfs_da_format.h" 20 #include "xfs_da_btree.h" 21 #include "xfs_attr.h" 22 #include "xfs_ioctl.h" 23 #include "xfs_parent.h" 24 #include "xfs_da_btree.h" 25 #include "xfs_handle.h" 26 #include "xfs_health.h" 27 #include "xfs_icache.h" 28 #include "xfs_export.h" 29 #include "xfs_xattr.h" 30 #include "xfs_acl.h" 31 32 #include <linux/namei.h> 33 34 static inline size_t 35 xfs_filehandle_fid_len(void) 36 { 37 struct xfs_handle *handle = NULL; 38 39 return sizeof(struct xfs_fid) - sizeof(handle->ha_fid.fid_len); 40 } 41 42 static inline size_t 43 xfs_filehandle_init( 44 struct xfs_mount *mp, 45 xfs_ino_t ino, 46 uint32_t gen, 47 struct xfs_handle *handle) 48 { 49 memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid)); 50 51 handle->ha_fid.fid_len = xfs_filehandle_fid_len(); 52 handle->ha_fid.fid_pad = 0; 53 handle->ha_fid.fid_gen = gen; 54 handle->ha_fid.fid_ino = ino; 55 56 return sizeof(struct xfs_handle); 57 } 58 59 static inline size_t 60 xfs_fshandle_init( 61 struct xfs_mount *mp, 62 struct xfs_handle *handle) 63 { 64 memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid)); 65 memset(&handle->ha_fid, 0, sizeof(handle->ha_fid)); 66 67 return sizeof(struct xfs_fsid); 68 } 69 70 /* 71 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to 72 * a file or fs handle. 73 * 74 * XFS_IOC_PATH_TO_FSHANDLE 75 * returns fs handle for a mount point or path within that mount point 76 * XFS_IOC_FD_TO_HANDLE 77 * returns full handle for a FD opened in user space 78 * XFS_IOC_PATH_TO_HANDLE 79 * returns full handle for a path 80 */ 81 int 82 xfs_find_handle( 83 unsigned int cmd, 84 xfs_fsop_handlereq_t *hreq) 85 { 86 int hsize; 87 xfs_handle_t handle; 88 struct inode *inode; 89 struct fd f = {NULL}; 90 struct path path; 91 int error; 92 struct xfs_inode *ip; 93 94 if (cmd == XFS_IOC_FD_TO_HANDLE) { 95 f = fdget(hreq->fd); 96 if (!f.file) 97 return -EBADF; 98 inode = file_inode(f.file); 99 } else { 100 error = user_path_at(AT_FDCWD, hreq->path, 0, &path); 101 if (error) 102 return error; 103 inode = d_inode(path.dentry); 104 } 105 ip = XFS_I(inode); 106 107 /* 108 * We can only generate handles for inodes residing on a XFS filesystem, 109 * and only for regular files, directories or symbolic links. 110 */ 111 error = -EINVAL; 112 if (inode->i_sb->s_magic != XFS_SB_MAGIC) 113 goto out_put; 114 115 error = -EBADF; 116 if (!S_ISREG(inode->i_mode) && 117 !S_ISDIR(inode->i_mode) && 118 !S_ISLNK(inode->i_mode)) 119 goto out_put; 120 121 122 memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); 123 124 if (cmd == XFS_IOC_PATH_TO_FSHANDLE) 125 hsize = xfs_fshandle_init(ip->i_mount, &handle); 126 else 127 hsize = xfs_filehandle_init(ip->i_mount, ip->i_ino, 128 inode->i_generation, &handle); 129 130 error = -EFAULT; 131 if (copy_to_user(hreq->ohandle, &handle, hsize) || 132 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) 133 goto out_put; 134 135 error = 0; 136 137 out_put: 138 if (cmd == XFS_IOC_FD_TO_HANDLE) 139 fdput(f); 140 else 141 path_put(&path); 142 return error; 143 } 144 145 /* 146 * No need to do permission checks on the various pathname components 147 * as the handle operations are privileged. 148 */ 149 STATIC int 150 xfs_handle_acceptable( 151 void *context, 152 struct dentry *dentry) 153 { 154 return 1; 155 } 156 157 /* Convert handle already copied to kernel space into a dentry. */ 158 static struct dentry * 159 xfs_khandle_to_dentry( 160 struct file *file, 161 struct xfs_handle *handle) 162 { 163 struct xfs_fid64 fid = { 164 .ino = handle->ha_fid.fid_ino, 165 .gen = handle->ha_fid.fid_gen, 166 }; 167 168 /* 169 * Only allow handle opens under a directory. 170 */ 171 if (!S_ISDIR(file_inode(file)->i_mode)) 172 return ERR_PTR(-ENOTDIR); 173 174 if (handle->ha_fid.fid_len != xfs_filehandle_fid_len()) 175 return ERR_PTR(-EINVAL); 176 177 return exportfs_decode_fh(file->f_path.mnt, (struct fid *)&fid, 3, 178 FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG, 179 xfs_handle_acceptable, NULL); 180 } 181 182 /* Convert handle already copied to kernel space into an xfs_inode. */ 183 static struct xfs_inode * 184 xfs_khandle_to_inode( 185 struct file *file, 186 struct xfs_handle *handle) 187 { 188 struct xfs_inode *ip = XFS_I(file_inode(file)); 189 struct xfs_mount *mp = ip->i_mount; 190 struct inode *inode; 191 192 if (!S_ISDIR(VFS_I(ip)->i_mode)) 193 return ERR_PTR(-ENOTDIR); 194 195 if (handle->ha_fid.fid_len != xfs_filehandle_fid_len()) 196 return ERR_PTR(-EINVAL); 197 198 inode = xfs_nfs_get_inode(mp->m_super, handle->ha_fid.fid_ino, 199 handle->ha_fid.fid_gen); 200 if (IS_ERR(inode)) 201 return ERR_CAST(inode); 202 203 return XFS_I(inode); 204 } 205 206 /* 207 * Convert userspace handle data into a dentry. 208 */ 209 struct dentry * 210 xfs_handle_to_dentry( 211 struct file *parfilp, 212 void __user *uhandle, 213 u32 hlen) 214 { 215 xfs_handle_t handle; 216 217 if (hlen != sizeof(xfs_handle_t)) 218 return ERR_PTR(-EINVAL); 219 if (copy_from_user(&handle, uhandle, hlen)) 220 return ERR_PTR(-EFAULT); 221 222 return xfs_khandle_to_dentry(parfilp, &handle); 223 } 224 225 STATIC struct dentry * 226 xfs_handlereq_to_dentry( 227 struct file *parfilp, 228 xfs_fsop_handlereq_t *hreq) 229 { 230 return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen); 231 } 232 233 int 234 xfs_open_by_handle( 235 struct file *parfilp, 236 xfs_fsop_handlereq_t *hreq) 237 { 238 const struct cred *cred = current_cred(); 239 int error; 240 int fd; 241 int permflag; 242 struct file *filp; 243 struct inode *inode; 244 struct dentry *dentry; 245 fmode_t fmode; 246 struct path path; 247 248 if (!capable(CAP_SYS_ADMIN)) 249 return -EPERM; 250 251 dentry = xfs_handlereq_to_dentry(parfilp, hreq); 252 if (IS_ERR(dentry)) 253 return PTR_ERR(dentry); 254 inode = d_inode(dentry); 255 256 /* Restrict xfs_open_by_handle to directories & regular files. */ 257 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { 258 error = -EPERM; 259 goto out_dput; 260 } 261 262 #if BITS_PER_LONG != 32 263 hreq->oflags |= O_LARGEFILE; 264 #endif 265 266 permflag = hreq->oflags; 267 fmode = OPEN_FMODE(permflag); 268 if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) && 269 (fmode & FMODE_WRITE) && IS_APPEND(inode)) { 270 error = -EPERM; 271 goto out_dput; 272 } 273 274 if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) { 275 error = -EPERM; 276 goto out_dput; 277 } 278 279 /* Can't write directories. */ 280 if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) { 281 error = -EISDIR; 282 goto out_dput; 283 } 284 285 fd = get_unused_fd_flags(0); 286 if (fd < 0) { 287 error = fd; 288 goto out_dput; 289 } 290 291 path.mnt = parfilp->f_path.mnt; 292 path.dentry = dentry; 293 filp = dentry_open(&path, hreq->oflags, cred); 294 dput(dentry); 295 if (IS_ERR(filp)) { 296 put_unused_fd(fd); 297 return PTR_ERR(filp); 298 } 299 300 if (S_ISREG(inode->i_mode)) { 301 filp->f_flags |= O_NOATIME; 302 filp->f_mode |= FMODE_NOCMTIME; 303 } 304 305 fd_install(fd, filp); 306 return fd; 307 308 out_dput: 309 dput(dentry); 310 return error; 311 } 312 313 int 314 xfs_readlink_by_handle( 315 struct file *parfilp, 316 xfs_fsop_handlereq_t *hreq) 317 { 318 struct dentry *dentry; 319 __u32 olen; 320 int error; 321 322 if (!capable(CAP_SYS_ADMIN)) 323 return -EPERM; 324 325 dentry = xfs_handlereq_to_dentry(parfilp, hreq); 326 if (IS_ERR(dentry)) 327 return PTR_ERR(dentry); 328 329 /* Restrict this handle operation to symlinks only. */ 330 if (!d_is_symlink(dentry)) { 331 error = -EINVAL; 332 goto out_dput; 333 } 334 335 if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { 336 error = -EFAULT; 337 goto out_dput; 338 } 339 340 error = vfs_readlink(dentry, hreq->ohandle, olen); 341 342 out_dput: 343 dput(dentry); 344 return error; 345 } 346 347 /* 348 * Format an attribute and copy it out to the user's buffer. 349 * Take care to check values and protect against them changing later, 350 * we may be reading them directly out of a user buffer. 351 */ 352 static void 353 xfs_ioc_attr_put_listent( 354 struct xfs_attr_list_context *context, 355 int flags, 356 unsigned char *name, 357 int namelen, 358 void *value, 359 int valuelen) 360 { 361 struct xfs_attrlist *alist = context->buffer; 362 struct xfs_attrlist_ent *aep; 363 int arraytop; 364 365 ASSERT(!context->seen_enough); 366 ASSERT(context->count >= 0); 367 ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); 368 ASSERT(context->firstu >= sizeof(*alist)); 369 ASSERT(context->firstu <= context->bufsize); 370 371 /* 372 * Only list entries in the right namespace. 373 */ 374 if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK)) 375 return; 376 377 arraytop = sizeof(*alist) + 378 context->count * sizeof(alist->al_offset[0]); 379 380 /* decrement by the actual bytes used by the attr */ 381 context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) + 382 namelen + 1, sizeof(uint32_t)); 383 if (context->firstu < arraytop) { 384 trace_xfs_attr_list_full(context); 385 alist->al_more = 1; 386 context->seen_enough = 1; 387 return; 388 } 389 390 aep = context->buffer + context->firstu; 391 aep->a_valuelen = valuelen; 392 memcpy(aep->a_name, name, namelen); 393 aep->a_name[namelen] = 0; 394 alist->al_offset[context->count++] = context->firstu; 395 alist->al_count = context->count; 396 trace_xfs_attr_list_add(context); 397 } 398 399 static unsigned int 400 xfs_attr_filter( 401 u32 ioc_flags) 402 { 403 if (ioc_flags & XFS_IOC_ATTR_ROOT) 404 return XFS_ATTR_ROOT; 405 if (ioc_flags & XFS_IOC_ATTR_SECURE) 406 return XFS_ATTR_SECURE; 407 return 0; 408 } 409 410 static inline enum xfs_attr_update 411 xfs_xattr_flags( 412 u32 ioc_flags, 413 void *value) 414 { 415 if (!value) 416 return XFS_ATTRUPDATE_REMOVE; 417 if (ioc_flags & XFS_IOC_ATTR_CREATE) 418 return XFS_ATTRUPDATE_CREATE; 419 if (ioc_flags & XFS_IOC_ATTR_REPLACE) 420 return XFS_ATTRUPDATE_REPLACE; 421 return XFS_ATTRUPDATE_UPSERT; 422 } 423 424 int 425 xfs_ioc_attr_list( 426 struct xfs_inode *dp, 427 void __user *ubuf, 428 size_t bufsize, 429 int flags, 430 struct xfs_attrlist_cursor __user *ucursor) 431 { 432 struct xfs_attr_list_context context = { }; 433 struct xfs_attrlist *alist; 434 void *buffer; 435 int error; 436 437 if (bufsize < sizeof(struct xfs_attrlist) || 438 bufsize > XFS_XATTR_LIST_MAX) 439 return -EINVAL; 440 441 /* 442 * Reject flags, only allow namespaces. 443 */ 444 if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE)) 445 return -EINVAL; 446 if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE)) 447 return -EINVAL; 448 449 /* 450 * Validate the cursor. 451 */ 452 if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor))) 453 return -EFAULT; 454 if (context.cursor.pad1 || context.cursor.pad2) 455 return -EINVAL; 456 if (!context.cursor.initted && 457 (context.cursor.hashval || context.cursor.blkno || 458 context.cursor.offset)) 459 return -EINVAL; 460 461 buffer = kvzalloc(bufsize, GFP_KERNEL); 462 if (!buffer) 463 return -ENOMEM; 464 465 /* 466 * Initialize the output buffer. 467 */ 468 context.dp = dp; 469 context.resynch = 1; 470 context.attr_filter = xfs_attr_filter(flags); 471 context.buffer = buffer; 472 context.bufsize = round_down(bufsize, sizeof(uint32_t)); 473 context.firstu = context.bufsize; 474 context.put_listent = xfs_ioc_attr_put_listent; 475 476 alist = context.buffer; 477 alist->al_count = 0; 478 alist->al_more = 0; 479 alist->al_offset[0] = context.bufsize; 480 481 error = xfs_attr_list(&context); 482 if (error) 483 goto out_free; 484 485 if (copy_to_user(ubuf, buffer, bufsize) || 486 copy_to_user(ucursor, &context.cursor, sizeof(context.cursor))) 487 error = -EFAULT; 488 out_free: 489 kvfree(buffer); 490 return error; 491 } 492 493 int 494 xfs_attrlist_by_handle( 495 struct file *parfilp, 496 struct xfs_fsop_attrlist_handlereq __user *p) 497 { 498 struct xfs_fsop_attrlist_handlereq al_hreq; 499 struct dentry *dentry; 500 int error = -ENOMEM; 501 502 if (!capable(CAP_SYS_ADMIN)) 503 return -EPERM; 504 if (copy_from_user(&al_hreq, p, sizeof(al_hreq))) 505 return -EFAULT; 506 507 dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq); 508 if (IS_ERR(dentry)) 509 return PTR_ERR(dentry); 510 511 error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer, 512 al_hreq.buflen, al_hreq.flags, &p->pos); 513 dput(dentry); 514 return error; 515 } 516 517 static int 518 xfs_attrmulti_attr_get( 519 struct inode *inode, 520 unsigned char *name, 521 unsigned char __user *ubuf, 522 uint32_t *len, 523 uint32_t flags) 524 { 525 struct xfs_da_args args = { 526 .dp = XFS_I(inode), 527 .attr_filter = xfs_attr_filter(flags), 528 .name = name, 529 .namelen = strlen(name), 530 .valuelen = *len, 531 }; 532 int error; 533 534 if (*len > XFS_XATTR_SIZE_MAX) 535 return -EINVAL; 536 537 error = xfs_attr_get(&args); 538 if (error) 539 goto out_kfree; 540 541 *len = args.valuelen; 542 if (copy_to_user(ubuf, args.value, args.valuelen)) 543 error = -EFAULT; 544 545 out_kfree: 546 kvfree(args.value); 547 return error; 548 } 549 550 static int 551 xfs_attrmulti_attr_set( 552 struct inode *inode, 553 unsigned char *name, 554 const unsigned char __user *ubuf, 555 uint32_t len, 556 uint32_t flags) 557 { 558 struct xfs_da_args args = { 559 .dp = XFS_I(inode), 560 .attr_filter = xfs_attr_filter(flags), 561 .name = name, 562 .namelen = strlen(name), 563 }; 564 int error; 565 566 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 567 return -EPERM; 568 569 if (ubuf) { 570 if (len > XFS_XATTR_SIZE_MAX) 571 return -EINVAL; 572 args.value = memdup_user(ubuf, len); 573 if (IS_ERR(args.value)) 574 return PTR_ERR(args.value); 575 args.valuelen = len; 576 } 577 578 error = xfs_attr_change(&args, xfs_xattr_flags(flags, args.value)); 579 if (!error && (flags & XFS_IOC_ATTR_ROOT)) 580 xfs_forget_acl(inode, name); 581 kfree(args.value); 582 return error; 583 } 584 585 int 586 xfs_ioc_attrmulti_one( 587 struct file *parfilp, 588 struct inode *inode, 589 uint32_t opcode, 590 void __user *uname, 591 void __user *value, 592 uint32_t *len, 593 uint32_t flags) 594 { 595 unsigned char *name; 596 int error; 597 598 if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE)) 599 return -EINVAL; 600 601 name = strndup_user(uname, MAXNAMELEN); 602 if (IS_ERR(name)) 603 return PTR_ERR(name); 604 605 switch (opcode) { 606 case ATTR_OP_GET: 607 error = xfs_attrmulti_attr_get(inode, name, value, len, flags); 608 break; 609 case ATTR_OP_REMOVE: 610 value = NULL; 611 *len = 0; 612 fallthrough; 613 case ATTR_OP_SET: 614 error = mnt_want_write_file(parfilp); 615 if (error) 616 break; 617 error = xfs_attrmulti_attr_set(inode, name, value, *len, flags); 618 mnt_drop_write_file(parfilp); 619 break; 620 default: 621 error = -EINVAL; 622 break; 623 } 624 625 kfree(name); 626 return error; 627 } 628 629 int 630 xfs_attrmulti_by_handle( 631 struct file *parfilp, 632 void __user *arg) 633 { 634 int error; 635 xfs_attr_multiop_t *ops; 636 xfs_fsop_attrmulti_handlereq_t am_hreq; 637 struct dentry *dentry; 638 unsigned int i, size; 639 640 if (!capable(CAP_SYS_ADMIN)) 641 return -EPERM; 642 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) 643 return -EFAULT; 644 645 /* overflow check */ 646 if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t)) 647 return -E2BIG; 648 649 dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq); 650 if (IS_ERR(dentry)) 651 return PTR_ERR(dentry); 652 653 error = -E2BIG; 654 size = am_hreq.opcount * sizeof(xfs_attr_multiop_t); 655 if (!size || size > 16 * PAGE_SIZE) 656 goto out_dput; 657 658 ops = memdup_user(am_hreq.ops, size); 659 if (IS_ERR(ops)) { 660 error = PTR_ERR(ops); 661 goto out_dput; 662 } 663 664 error = 0; 665 for (i = 0; i < am_hreq.opcount; i++) { 666 ops[i].am_error = xfs_ioc_attrmulti_one(parfilp, 667 d_inode(dentry), ops[i].am_opcode, 668 ops[i].am_attrname, ops[i].am_attrvalue, 669 &ops[i].am_length, ops[i].am_flags); 670 } 671 672 if (copy_to_user(am_hreq.ops, ops, size)) 673 error = -EFAULT; 674 675 kfree(ops); 676 out_dput: 677 dput(dentry); 678 return error; 679 } 680 681 struct xfs_getparents_ctx { 682 struct xfs_attr_list_context context; 683 struct xfs_getparents_by_handle gph; 684 685 /* File to target */ 686 struct xfs_inode *ip; 687 688 /* Internal buffer where we format records */ 689 void *krecords; 690 691 /* Last record filled out */ 692 struct xfs_getparents_rec *lastrec; 693 694 unsigned int count; 695 }; 696 697 static inline unsigned int 698 xfs_getparents_rec_sizeof( 699 unsigned int namelen) 700 { 701 return round_up(sizeof(struct xfs_getparents_rec) + namelen + 1, 702 sizeof(uint64_t)); 703 } 704 705 static void 706 xfs_getparents_put_listent( 707 struct xfs_attr_list_context *context, 708 int flags, 709 unsigned char *name, 710 int namelen, 711 void *value, 712 int valuelen) 713 { 714 struct xfs_getparents_ctx *gpx = 715 container_of(context, struct xfs_getparents_ctx, context); 716 struct xfs_inode *ip = context->dp; 717 struct xfs_mount *mp = ip->i_mount; 718 struct xfs_getparents *gp = &gpx->gph.gph_request; 719 struct xfs_getparents_rec *gpr = gpx->krecords + context->firstu; 720 unsigned short reclen = 721 xfs_getparents_rec_sizeof(namelen); 722 xfs_ino_t ino; 723 uint32_t gen; 724 int error; 725 726 if (!(flags & XFS_ATTR_PARENT)) 727 return; 728 729 error = xfs_parent_from_attr(mp, flags, name, namelen, value, valuelen, 730 &ino, &gen); 731 if (error) { 732 xfs_inode_mark_sick(ip, XFS_SICK_INO_PARENT); 733 context->seen_enough = -EFSCORRUPTED; 734 return; 735 } 736 737 /* 738 * We found a parent pointer, but we've filled up the buffer. Signal 739 * to the caller that we did /not/ reach the end of the parent pointer 740 * recordset. 741 */ 742 if (context->firstu > context->bufsize - reclen) { 743 context->seen_enough = 1; 744 return; 745 } 746 747 /* Format the parent pointer directly into the caller buffer. */ 748 gpr->gpr_reclen = reclen; 749 xfs_filehandle_init(mp, ino, gen, &gpr->gpr_parent); 750 memcpy(gpr->gpr_name, name, namelen); 751 gpr->gpr_name[namelen] = 0; 752 753 trace_xfs_getparents_put_listent(ip, gp, context, gpr); 754 755 context->firstu += reclen; 756 gpx->count++; 757 gpx->lastrec = gpr; 758 } 759 760 /* Expand the last record to fill the rest of the caller's buffer. */ 761 static inline void 762 xfs_getparents_expand_lastrec( 763 struct xfs_getparents_ctx *gpx) 764 { 765 struct xfs_getparents *gp = &gpx->gph.gph_request; 766 struct xfs_getparents_rec *gpr = gpx->lastrec; 767 768 if (!gpx->lastrec) 769 gpr = gpx->krecords; 770 771 gpr->gpr_reclen = gp->gp_bufsize - ((void *)gpr - gpx->krecords); 772 773 trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr); 774 } 775 776 /* Retrieve the parent pointers for a given inode. */ 777 STATIC int 778 xfs_getparents( 779 struct xfs_getparents_ctx *gpx) 780 { 781 struct xfs_getparents *gp = &gpx->gph.gph_request; 782 struct xfs_inode *ip = gpx->ip; 783 struct xfs_mount *mp = ip->i_mount; 784 size_t bufsize; 785 int error; 786 787 /* Check size of buffer requested by user */ 788 if (gp->gp_bufsize > XFS_XATTR_LIST_MAX) 789 return -ENOMEM; 790 if (gp->gp_bufsize < xfs_getparents_rec_sizeof(1)) 791 return -EINVAL; 792 793 if (gp->gp_iflags & ~XFS_GETPARENTS_IFLAGS_ALL) 794 return -EINVAL; 795 if (gp->gp_reserved) 796 return -EINVAL; 797 798 bufsize = round_down(gp->gp_bufsize, sizeof(uint64_t)); 799 gpx->krecords = kvzalloc(bufsize, GFP_KERNEL); 800 if (!gpx->krecords) { 801 bufsize = min(bufsize, PAGE_SIZE); 802 gpx->krecords = kvzalloc(bufsize, GFP_KERNEL); 803 if (!gpx->krecords) 804 return -ENOMEM; 805 } 806 807 gpx->context.dp = ip; 808 gpx->context.resynch = 1; 809 gpx->context.put_listent = xfs_getparents_put_listent; 810 gpx->context.bufsize = bufsize; 811 /* firstu is used to track the bytes filled in the buffer */ 812 gpx->context.firstu = 0; 813 814 /* Copy the cursor provided by caller */ 815 memcpy(&gpx->context.cursor, &gp->gp_cursor, 816 sizeof(struct xfs_attrlist_cursor)); 817 gpx->count = 0; 818 gp->gp_oflags = 0; 819 820 trace_xfs_getparents_begin(ip, gp, &gpx->context.cursor); 821 822 error = xfs_attr_list(&gpx->context); 823 if (error) 824 goto out_free_buf; 825 if (gpx->context.seen_enough < 0) { 826 error = gpx->context.seen_enough; 827 goto out_free_buf; 828 } 829 xfs_getparents_expand_lastrec(gpx); 830 831 /* Update the caller with the current cursor position */ 832 memcpy(&gp->gp_cursor, &gpx->context.cursor, 833 sizeof(struct xfs_attrlist_cursor)); 834 835 /* Is this the root directory? */ 836 if (ip->i_ino == mp->m_sb.sb_rootino) 837 gp->gp_oflags |= XFS_GETPARENTS_OFLAG_ROOT; 838 839 if (gpx->context.seen_enough == 0) { 840 /* 841 * If we did not run out of buffer space, then we reached the 842 * end of the pptr recordset, so set the DONE flag. 843 */ 844 gp->gp_oflags |= XFS_GETPARENTS_OFLAG_DONE; 845 } else if (gpx->count == 0) { 846 /* 847 * If we ran out of buffer space before copying any parent 848 * pointers at all, the caller's buffer was too short. Tell 849 * userspace that, erm, the message is too long. 850 */ 851 error = -EMSGSIZE; 852 goto out_free_buf; 853 } 854 855 trace_xfs_getparents_end(ip, gp, &gpx->context.cursor); 856 857 ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize); 858 859 /* Copy the records to userspace. */ 860 if (copy_to_user(u64_to_user_ptr(gpx->gph.gph_request.gp_buffer), 861 gpx->krecords, gpx->context.firstu)) 862 error = -EFAULT; 863 864 out_free_buf: 865 kvfree(gpx->krecords); 866 gpx->krecords = NULL; 867 return error; 868 } 869 870 /* Retrieve the parents of this file and pass them back to userspace. */ 871 int 872 xfs_ioc_getparents( 873 struct file *file, 874 struct xfs_getparents __user *ureq) 875 { 876 struct xfs_getparents_ctx gpx = { 877 .ip = XFS_I(file_inode(file)), 878 }; 879 struct xfs_getparents *kreq = &gpx.gph.gph_request; 880 struct xfs_mount *mp = gpx.ip->i_mount; 881 int error; 882 883 if (!capable(CAP_SYS_ADMIN)) 884 return -EPERM; 885 if (!xfs_has_parent(mp)) 886 return -EOPNOTSUPP; 887 if (copy_from_user(kreq, ureq, sizeof(*kreq))) 888 return -EFAULT; 889 890 error = xfs_getparents(&gpx); 891 if (error) 892 return error; 893 894 if (copy_to_user(ureq, kreq, sizeof(*kreq))) 895 return -EFAULT; 896 897 return 0; 898 } 899 900 /* Retrieve the parents of this file handle and pass them back to userspace. */ 901 int 902 xfs_ioc_getparents_by_handle( 903 struct file *file, 904 struct xfs_getparents_by_handle __user *ureq) 905 { 906 struct xfs_getparents_ctx gpx = { }; 907 struct xfs_inode *ip = XFS_I(file_inode(file)); 908 struct xfs_mount *mp = ip->i_mount; 909 struct xfs_getparents_by_handle *kreq = &gpx.gph; 910 struct xfs_handle *handle = &kreq->gph_handle; 911 int error; 912 913 if (!capable(CAP_SYS_ADMIN)) 914 return -EPERM; 915 if (!xfs_has_parent(mp)) 916 return -EOPNOTSUPP; 917 if (copy_from_user(kreq, ureq, sizeof(*kreq))) 918 return -EFAULT; 919 920 /* 921 * We don't use exportfs_decode_fh because it does too much work here. 922 * If the handle refers to a directory, the exportfs code will walk 923 * upwards through the directory tree to connect the dentries to the 924 * root directory dentry. For GETPARENTS we don't care about that 925 * because we're not actually going to open a file descriptor; we only 926 * want to open an inode and read its parent pointers. 927 * 928 * Note that xfs_scrub uses GETPARENTS to log that it will try to fix a 929 * corrupted file's metadata. For this usecase we would really rather 930 * userspace single-step the path reconstruction to avoid loops or 931 * other strange things if the directory tree is corrupt. 932 */ 933 gpx.ip = xfs_khandle_to_inode(file, handle); 934 if (IS_ERR(gpx.ip)) 935 return PTR_ERR(gpx.ip); 936 937 error = xfs_getparents(&gpx); 938 if (error) 939 goto out_rele; 940 941 if (copy_to_user(ureq, kreq, sizeof(*kreq))) 942 error = -EFAULT; 943 944 out_rele: 945 xfs_irele(gpx.ip); 946 return error; 947 } 948