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