1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 35 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/buf.h> 41 #include <sys/conf.h> 42 #include <sys/sysent.h> 43 #include <sys/malloc.h> 44 #include <sys/mount.h> 45 #include <sys/mountctl.h> 46 #include <sys/sysproto.h> 47 #include <sys/filedesc.h> 48 #include <sys/kernel.h> 49 #include <sys/fcntl.h> 50 #include <sys/file.h> 51 #include <sys/linker.h> 52 #include <sys/stat.h> 53 #include <sys/unistd.h> 54 #include <sys/vnode.h> 55 #include <sys/proc.h> 56 #include <sys/priv.h> 57 #include <sys/jail.h> 58 #include <sys/namei.h> 59 #include <sys/nlookup.h> 60 #include <sys/dirent.h> 61 #include <sys/extattr.h> 62 #include <sys/spinlock.h> 63 #include <sys/kern_syscall.h> 64 #include <sys/objcache.h> 65 #include <sys/sysctl.h> 66 67 #include <sys/buf2.h> 68 #include <sys/file2.h> 69 #include <sys/spinlock2.h> 70 71 #include <vm/vm.h> 72 #include <vm/vm_object.h> 73 #include <vm/vm_page.h> 74 75 #include <machine/limits.h> 76 #include <machine/stdarg.h> 77 78 static void mount_warning(struct mount *mp, const char *ctl, ...) 79 __printflike(2, 3); 80 static int mount_path(struct proc *p, struct mount *mp, char **rb, char **fb); 81 static int checkvp_chdir (struct vnode *vn, struct thread *td); 82 static void checkdirs (struct nchandle *old_nch, struct nchandle *new_nch); 83 static int chroot_refuse_vdir_fds (struct filedesc *fdp); 84 static int chroot_visible_mnt(struct mount *mp, struct proc *p); 85 static int getutimes (struct timeval *, struct timespec *); 86 static int getutimens (const struct timespec *, struct timespec *, int *); 87 static int setfown (struct mount *, struct vnode *, uid_t, gid_t); 88 static int setfmode (struct vnode *, int); 89 static int setfflags (struct vnode *, int); 90 static int setutimes (struct vnode *, struct vattr *, 91 const struct timespec *, int); 92 static int usermount = 0; /* if 1, non-root can mount fs. */ 93 94 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 95 "Allow non-root users to mount filesystems"); 96 97 /* 98 * Virtual File System System Calls 99 */ 100 101 /* 102 * Mount a file system. 103 * 104 * mount_args(char *type, char *path, int flags, caddr_t data) 105 * 106 * MPALMOSTSAFE 107 */ 108 int 109 sys_mount(struct mount_args *uap) 110 { 111 struct thread *td = curthread; 112 struct vnode *vp; 113 struct nchandle nch; 114 struct mount *mp, *nullmp; 115 struct vfsconf *vfsp; 116 int error, flag = 0, flag2 = 0; 117 int hasmount; 118 struct vattr va; 119 struct nlookupdata nd; 120 char fstypename[MFSNAMELEN]; 121 struct ucred *cred; 122 123 cred = td->td_ucred; 124 if (jailed(cred)) { 125 error = EPERM; 126 goto done; 127 } 128 if (usermount == 0 && (error = priv_check(td, PRIV_ROOT))) 129 goto done; 130 131 /* 132 * Do not allow NFS export by non-root users. 133 */ 134 if (uap->flags & MNT_EXPORTED) { 135 error = priv_check(td, PRIV_ROOT); 136 if (error) 137 goto done; 138 } 139 /* 140 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users 141 */ 142 if (priv_check(td, PRIV_ROOT)) 143 uap->flags |= MNT_NOSUID | MNT_NODEV; 144 145 /* 146 * Lookup the requested path and extract the nch and vnode. 147 */ 148 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 149 if (error == 0) { 150 if ((error = nlookup(&nd)) == 0) { 151 if (nd.nl_nch.ncp->nc_vp == NULL) 152 error = ENOENT; 153 } 154 } 155 if (error) { 156 nlookup_done(&nd); 157 goto done; 158 } 159 160 /* 161 * If the target filesystem is resolved via a nullfs mount, then 162 * nd.nl_nch.mount will be pointing to the nullfs mount structure 163 * instead of the target file system. We need it in case we are 164 * doing an update. 165 */ 166 nullmp = nd.nl_nch.mount; 167 168 /* 169 * Extract the locked+refd ncp and cleanup the nd structure 170 */ 171 nch = nd.nl_nch; 172 cache_zero(&nd.nl_nch); 173 nlookup_done(&nd); 174 175 if ((nch.ncp->nc_flag & NCF_ISMOUNTPT) && 176 (mp = cache_findmount(&nch)) != NULL) { 177 cache_dropmount(mp); 178 hasmount = 1; 179 } else { 180 hasmount = 0; 181 } 182 183 184 /* 185 * now we have the locked ref'd nch and unreferenced vnode. 186 */ 187 vp = nch.ncp->nc_vp; 188 if ((error = vget(vp, LK_EXCLUSIVE)) != 0) { 189 cache_put(&nch); 190 goto done; 191 } 192 cache_unlock(&nch); 193 194 /* 195 * Extract the file system type. We need to know this early, to take 196 * appropriate actions if we are dealing with a nullfs. 197 */ 198 if ((error = copyinstr(uap->type, fstypename, MFSNAMELEN, NULL)) != 0) { 199 cache_drop(&nch); 200 vput(vp); 201 goto done; 202 } 203 204 /* 205 * Now we have an unlocked ref'd nch and a locked ref'd vp 206 */ 207 if (uap->flags & MNT_UPDATE) { 208 if ((vp->v_flag & (VROOT|VPFSROOT)) == 0) { 209 cache_drop(&nch); 210 vput(vp); 211 error = EINVAL; 212 goto done; 213 } 214 215 if (strncmp(fstypename, "null", 5) == 0) { 216 KKASSERT(nullmp); 217 mp = nullmp; 218 } else { 219 mp = vp->v_mount; 220 } 221 222 flag = mp->mnt_flag; 223 flag2 = mp->mnt_kern_flag; 224 /* 225 * We only allow the filesystem to be reloaded if it 226 * is currently mounted read-only. 227 */ 228 if ((uap->flags & MNT_RELOAD) && 229 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 230 cache_drop(&nch); 231 vput(vp); 232 error = EOPNOTSUPP; /* Needs translation */ 233 goto done; 234 } 235 /* 236 * Only root, or the user that did the original mount is 237 * permitted to update it. 238 */ 239 if (mp->mnt_stat.f_owner != cred->cr_uid && 240 (error = priv_check(td, PRIV_ROOT))) { 241 cache_drop(&nch); 242 vput(vp); 243 goto done; 244 } 245 if (vfs_busy(mp, LK_NOWAIT)) { 246 cache_drop(&nch); 247 vput(vp); 248 error = EBUSY; 249 goto done; 250 } 251 if (hasmount) { 252 cache_drop(&nch); 253 vfs_unbusy(mp); 254 vput(vp); 255 error = EBUSY; 256 goto done; 257 } 258 mp->mnt_flag |= 259 uap->flags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE); 260 lwkt_gettoken(&mp->mnt_token); 261 vn_unlock(vp); 262 vfsp = mp->mnt_vfc; 263 goto update; 264 } 265 266 /* 267 * If the user is not root, ensure that they own the directory 268 * onto which we are attempting to mount. 269 */ 270 if ((error = VOP_GETATTR(vp, &va)) || 271 (va.va_uid != cred->cr_uid && 272 (error = priv_check(td, PRIV_ROOT)))) { 273 cache_drop(&nch); 274 vput(vp); 275 goto done; 276 } 277 if ((error = vinvalbuf(vp, V_SAVE, 0, 0)) != 0) { 278 cache_drop(&nch); 279 vput(vp); 280 goto done; 281 } 282 if (vp->v_type != VDIR) { 283 cache_drop(&nch); 284 vput(vp); 285 error = ENOTDIR; 286 goto done; 287 } 288 if (vp->v_mount->mnt_kern_flag & MNTK_NOSTKMNT) { 289 cache_drop(&nch); 290 vput(vp); 291 error = EPERM; 292 goto done; 293 } 294 vfsp = vfsconf_find_by_name(fstypename); 295 if (vfsp == NULL) { 296 linker_file_t lf; 297 298 /* Only load modules for root (very important!) */ 299 if ((error = priv_check(td, PRIV_ROOT)) != 0) { 300 cache_drop(&nch); 301 vput(vp); 302 goto done; 303 } 304 error = linker_load_file(fstypename, &lf); 305 if (error || lf == NULL) { 306 cache_drop(&nch); 307 vput(vp); 308 if (lf == NULL) 309 error = ENODEV; 310 goto done; 311 } 312 lf->userrefs++; 313 /* lookup again, see if the VFS was loaded */ 314 vfsp = vfsconf_find_by_name(fstypename); 315 if (vfsp == NULL) { 316 lf->userrefs--; 317 linker_file_unload(lf); 318 cache_drop(&nch); 319 vput(vp); 320 error = ENODEV; 321 goto done; 322 } 323 } 324 if (hasmount) { 325 cache_drop(&nch); 326 vput(vp); 327 error = EBUSY; 328 goto done; 329 } 330 331 /* 332 * Allocate and initialize the filesystem. 333 */ 334 mp = kmalloc(sizeof(struct mount), M_MOUNT, M_ZERO|M_WAITOK); 335 mount_init(mp); 336 vfs_busy(mp, LK_NOWAIT); 337 mp->mnt_op = vfsp->vfc_vfsops; 338 mp->mnt_vfc = vfsp; 339 mp->mnt_pbuf_count = nswbuf_kva / NSWBUF_SPLIT; 340 vfsp->vfc_refcount++; 341 mp->mnt_stat.f_type = vfsp->vfc_typenum; 342 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 343 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 344 mp->mnt_stat.f_owner = cred->cr_uid; 345 lwkt_gettoken(&mp->mnt_token); 346 vn_unlock(vp); 347 update: 348 /* 349 * (per-mount token acquired at this point) 350 * 351 * Set the mount level flags. 352 */ 353 if (uap->flags & MNT_RDONLY) 354 mp->mnt_flag |= MNT_RDONLY; 355 else if (mp->mnt_flag & MNT_RDONLY) 356 mp->mnt_kern_flag |= MNTK_WANTRDWR; 357 mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | 358 MNT_SYNCHRONOUS | MNT_ASYNC | MNT_NOATIME | 359 MNT_NOSYMFOLLOW | MNT_IGNORE | MNT_TRIM | 360 MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | 361 MNT_AUTOMOUNTED); 362 mp->mnt_flag |= uap->flags & (MNT_NOSUID | MNT_NOEXEC | 363 MNT_NODEV | MNT_SYNCHRONOUS | MNT_ASYNC | MNT_FORCE | 364 MNT_NOSYMFOLLOW | MNT_IGNORE | MNT_TRIM | 365 MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | 366 MNT_AUTOMOUNTED); 367 368 /* 369 * Pre-set the mount's ALL_MPSAFE flags if specified in the vfsconf. 370 * This way the initial VFS_MOUNT() call will also be MPSAFE. 371 */ 372 if (vfsp->vfc_flags & VFCF_MPSAFE) 373 mp->mnt_kern_flag |= MNTK_ALL_MPSAFE; 374 375 /* 376 * Mount the filesystem. 377 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 378 * get. 379 */ 380 error = VFS_MOUNT(mp, uap->path, uap->data, cred); 381 if (mp->mnt_flag & MNT_UPDATE) { 382 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 383 mp->mnt_flag &= ~MNT_RDONLY; 384 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE); 385 mp->mnt_kern_flag &=~ MNTK_WANTRDWR; 386 if (error) { 387 mp->mnt_flag = flag; 388 mp->mnt_kern_flag = flag2; 389 } 390 lwkt_reltoken(&mp->mnt_token); 391 vfs_unbusy(mp); 392 vrele(vp); 393 cache_drop(&nch); 394 goto done; 395 } 396 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 397 398 /* 399 * Put the new filesystem on the mount list after root. The mount 400 * point gets its own mnt_ncmountpt (unless the VFS already set one 401 * up) which represents the root of the mount. The lookup code 402 * detects the mount point going forward and checks the root of 403 * the mount going backwards. 404 * 405 * It is not necessary to invalidate or purge the vnode underneath 406 * because elements under the mount will be given their own glue 407 * namecache record. 408 */ 409 if (!error) { 410 if (mp->mnt_ncmountpt.ncp == NULL) { 411 /* 412 * allocate, then unlock, but leave the ref intact 413 */ 414 cache_allocroot(&mp->mnt_ncmountpt, mp, NULL); 415 cache_unlock(&mp->mnt_ncmountpt); 416 } 417 vn_unlock(vp); 418 mp->mnt_ncmounton = nch; /* inherits ref */ 419 cache_lock(&nch); 420 nch.ncp->nc_flag |= NCF_ISMOUNTPT; 421 cache_unlock(&nch); 422 cache_ismounting(mp); 423 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 424 425 mountlist_insert(mp, MNTINS_LAST); 426 vn_unlock(vp); 427 checkdirs(&mp->mnt_ncmounton, &mp->mnt_ncmountpt); 428 error = vfs_allocate_syncvnode(mp); 429 lwkt_reltoken(&mp->mnt_token); 430 vfs_unbusy(mp); 431 error = VFS_START(mp, 0); 432 vrele(vp); 433 KNOTE(&fs_klist, VQ_MOUNT); 434 } else { 435 vn_syncer_thr_stop(mp); 436 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_coherency_ops); 437 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_journal_ops); 438 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_norm_ops); 439 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_spec_ops); 440 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_fifo_ops); 441 mp->mnt_vfc->vfc_refcount--; 442 lwkt_reltoken(&mp->mnt_token); 443 vfs_unbusy(mp); 444 kfree(mp, M_MOUNT); 445 cache_drop(&nch); 446 vput(vp); 447 } 448 done: 449 return (error); 450 } 451 452 /* 453 * Scan all active processes to see if any of them have a current 454 * or root directory onto which the new filesystem has just been 455 * mounted. If so, replace them with the new mount point. 456 * 457 * Both old_nch and new_nch are ref'd on call but not locked. 458 * new_nch must be temporarily locked so it can be associated with the 459 * vnode representing the root of the mount point. 460 */ 461 struct checkdirs_info { 462 struct nchandle old_nch; 463 struct nchandle new_nch; 464 struct vnode *old_vp; 465 struct vnode *new_vp; 466 }; 467 468 static int checkdirs_callback(struct proc *p, void *data); 469 470 static void 471 checkdirs(struct nchandle *old_nch, struct nchandle *new_nch) 472 { 473 struct checkdirs_info info; 474 struct vnode *olddp; 475 struct vnode *newdp; 476 struct mount *mp; 477 478 /* 479 * If the old mount point's vnode has a usecount of 1, it is not 480 * being held as a descriptor anywhere. 481 */ 482 olddp = old_nch->ncp->nc_vp; 483 if (olddp == NULL || VREFCNT(olddp) == 1) 484 return; 485 486 /* 487 * Force the root vnode of the new mount point to be resolved 488 * so we can update any matching processes. 489 */ 490 mp = new_nch->mount; 491 if (VFS_ROOT(mp, &newdp)) 492 panic("mount: lost mount"); 493 vn_unlock(newdp); 494 cache_lock(new_nch); 495 vn_lock(newdp, LK_EXCLUSIVE | LK_RETRY); 496 cache_setunresolved(new_nch); 497 cache_setvp(new_nch, newdp); 498 cache_unlock(new_nch); 499 500 /* 501 * Special handling of the root node 502 */ 503 if (rootvnode == olddp) { 504 vref(newdp); 505 vfs_cache_setroot(newdp, cache_hold(new_nch)); 506 } 507 508 /* 509 * Pass newdp separately so the callback does not have to access 510 * it via new_nch->ncp->nc_vp. 511 */ 512 info.old_nch = *old_nch; 513 info.new_nch = *new_nch; 514 info.new_vp = newdp; 515 allproc_scan(checkdirs_callback, &info); 516 vput(newdp); 517 } 518 519 /* 520 * NOTE: callback is not MP safe because the scanned process's filedesc 521 * structure can be ripped out from under us, amoung other things. 522 */ 523 static int 524 checkdirs_callback(struct proc *p, void *data) 525 { 526 struct checkdirs_info *info = data; 527 struct filedesc *fdp; 528 struct nchandle ncdrop1; 529 struct nchandle ncdrop2; 530 struct vnode *vprele1; 531 struct vnode *vprele2; 532 533 if ((fdp = p->p_fd) != NULL) { 534 cache_zero(&ncdrop1); 535 cache_zero(&ncdrop2); 536 vprele1 = NULL; 537 vprele2 = NULL; 538 539 /* 540 * MPUNSAFE - XXX fdp can be pulled out from under a 541 * foreign process. 542 * 543 * A shared filedesc is ok, we don't have to copy it 544 * because we are making this change globally. 545 */ 546 spin_lock(&fdp->fd_spin); 547 if (fdp->fd_ncdir.mount == info->old_nch.mount && 548 fdp->fd_ncdir.ncp == info->old_nch.ncp) { 549 vprele1 = fdp->fd_cdir; 550 vref(info->new_vp); 551 fdp->fd_cdir = info->new_vp; 552 ncdrop1 = fdp->fd_ncdir; 553 cache_copy(&info->new_nch, &fdp->fd_ncdir); 554 } 555 if (fdp->fd_nrdir.mount == info->old_nch.mount && 556 fdp->fd_nrdir.ncp == info->old_nch.ncp) { 557 vprele2 = fdp->fd_rdir; 558 vref(info->new_vp); 559 fdp->fd_rdir = info->new_vp; 560 ncdrop2 = fdp->fd_nrdir; 561 cache_copy(&info->new_nch, &fdp->fd_nrdir); 562 } 563 spin_unlock(&fdp->fd_spin); 564 if (ncdrop1.ncp) 565 cache_drop(&ncdrop1); 566 if (ncdrop2.ncp) 567 cache_drop(&ncdrop2); 568 if (vprele1) 569 vrele(vprele1); 570 if (vprele2) 571 vrele(vprele2); 572 } 573 return(0); 574 } 575 576 /* 577 * Unmount a file system. 578 * 579 * Note: unmount takes a path to the vnode mounted on as argument, 580 * not special file (as before). 581 * 582 * umount_args(char *path, int flags) 583 * 584 * MPALMOSTSAFE 585 */ 586 int 587 sys_unmount(struct unmount_args *uap) 588 { 589 struct thread *td = curthread; 590 struct proc *p __debugvar = td->td_proc; 591 struct mount *mp = NULL; 592 struct nlookupdata nd; 593 int error; 594 595 KKASSERT(p); 596 if (td->td_ucred->cr_prison != NULL) { 597 error = EPERM; 598 goto done; 599 } 600 if (usermount == 0 && (error = priv_check(td, PRIV_ROOT))) 601 goto done; 602 603 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 604 if (error == 0) 605 error = nlookup(&nd); 606 if (error) 607 goto out; 608 609 mp = nd.nl_nch.mount; 610 611 /* 612 * Only root, or the user that did the original mount is 613 * permitted to unmount this filesystem. 614 */ 615 if ((mp->mnt_stat.f_owner != td->td_ucred->cr_uid) && 616 (error = priv_check(td, PRIV_ROOT))) 617 goto out; 618 619 /* 620 * Don't allow unmounting the root file system. 621 */ 622 if (mp->mnt_flag & MNT_ROOTFS) { 623 error = EINVAL; 624 goto out; 625 } 626 627 /* 628 * Must be the root of the filesystem 629 */ 630 if (nd.nl_nch.ncp != mp->mnt_ncmountpt.ncp) { 631 error = EINVAL; 632 goto out; 633 } 634 635 out: 636 nlookup_done(&nd); 637 if (error == 0) 638 error = dounmount(mp, uap->flags); 639 done: 640 return (error); 641 } 642 643 /* 644 * Do the actual file system unmount. 645 */ 646 static int 647 dounmount_interlock(struct mount *mp) 648 { 649 if (mp->mnt_kern_flag & MNTK_UNMOUNT) 650 return (EBUSY); 651 mp->mnt_kern_flag |= MNTK_UNMOUNT; 652 return(0); 653 } 654 655 static int 656 unmount_allproc_cb(struct proc *p, void *arg) 657 { 658 struct mount *mp; 659 660 if (p->p_textnch.ncp == NULL) 661 return 0; 662 663 mp = (struct mount *)arg; 664 if (p->p_textnch.mount == mp) 665 cache_drop(&p->p_textnch); 666 667 return 0; 668 } 669 670 int 671 dounmount(struct mount *mp, int flags) 672 { 673 struct namecache *ncp; 674 struct nchandle nch; 675 struct vnode *vp; 676 int error; 677 int async_flag; 678 int lflags; 679 int freeok = 1; 680 int retry; 681 682 lwkt_gettoken(&mp->mnt_token); 683 /* 684 * Exclusive access for unmounting purposes 685 */ 686 if ((error = mountlist_interlock(dounmount_interlock, mp)) != 0) 687 goto out; 688 689 /* 690 * Allow filesystems to detect that a forced unmount is in progress. 691 */ 692 if (flags & MNT_FORCE) 693 mp->mnt_kern_flag |= MNTK_UNMOUNTF; 694 lflags = LK_EXCLUSIVE | ((flags & MNT_FORCE) ? 0 : LK_TIMELOCK); 695 error = lockmgr(&mp->mnt_lock, lflags); 696 if (error) { 697 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 698 if (mp->mnt_kern_flag & MNTK_MWAIT) { 699 mp->mnt_kern_flag &= ~MNTK_MWAIT; 700 wakeup(mp); 701 } 702 goto out; 703 } 704 705 if (mp->mnt_flag & MNT_EXPUBLIC) 706 vfs_setpublicfs(NULL, NULL, NULL); 707 708 vfs_msync(mp, MNT_WAIT); 709 async_flag = mp->mnt_flag & MNT_ASYNC; 710 mp->mnt_flag &=~ MNT_ASYNC; 711 712 /* 713 * If this filesystem isn't aliasing other filesystems, 714 * try to invalidate any remaining namecache entries and 715 * check the count afterwords. 716 */ 717 if ((mp->mnt_kern_flag & MNTK_NCALIASED) == 0) { 718 cache_lock(&mp->mnt_ncmountpt); 719 cache_inval(&mp->mnt_ncmountpt, CINV_DESTROY|CINV_CHILDREN); 720 cache_unlock(&mp->mnt_ncmountpt); 721 722 cache_clearmntcache(); 723 if ((ncp = mp->mnt_ncmountpt.ncp) != NULL && 724 (ncp->nc_refs != 1 || TAILQ_FIRST(&ncp->nc_list))) { 725 allproc_scan(&unmount_allproc_cb, mp); 726 } 727 728 cache_clearmntcache(); 729 if ((ncp = mp->mnt_ncmountpt.ncp) != NULL && 730 (ncp->nc_refs != 1 || TAILQ_FIRST(&ncp->nc_list))) { 731 732 if ((flags & MNT_FORCE) == 0) { 733 error = EBUSY; 734 mount_warning(mp, "Cannot unmount: " 735 "%d namecache " 736 "references still " 737 "present", 738 ncp->nc_refs - 1); 739 } else { 740 mount_warning(mp, "Forced unmount: " 741 "%d namecache " 742 "references still " 743 "present", 744 ncp->nc_refs - 1); 745 freeok = 0; 746 } 747 } 748 } 749 750 /* 751 * Decomission our special mnt_syncer vnode. This also stops 752 * the vnlru code. If we are unable to unmount we recommission 753 * the vnode. 754 * 755 * Then sync the filesystem. 756 */ 757 if ((vp = mp->mnt_syncer) != NULL) { 758 mp->mnt_syncer = NULL; 759 atomic_set_int(&vp->v_refcnt, VREF_FINALIZE); 760 vrele(vp); 761 } 762 if ((mp->mnt_flag & MNT_RDONLY) == 0) 763 VFS_SYNC(mp, MNT_WAIT); 764 765 /* 766 * nchandle records ref the mount structure. Expect a count of 1 767 * (our mount->mnt_ncmountpt). 768 * 769 * Scans can get temporary refs on a mountpoint (thought really 770 * heavy duty stuff like cache_findmount() do not). 771 */ 772 if (mp->mnt_refs != 1) 773 cache_clearmntcache(); 774 for (retry = 0; retry < 10 && mp->mnt_refs != 1; ++retry) { 775 cache_unmounting(mp); 776 tsleep(&mp->mnt_refs, 0, "mntbsy", hz / 10 + 1); 777 cache_clearmntcache(); 778 } 779 if (mp->mnt_refs != 1) { 780 if ((flags & MNT_FORCE) == 0) { 781 mount_warning(mp, "Cannot unmount: " 782 "%d mount refs still present", 783 mp->mnt_refs - 1); 784 error = EBUSY; 785 } else { 786 mount_warning(mp, "Forced unmount: " 787 "%d mount refs still present", 788 mp->mnt_refs - 1); 789 freeok = 0; 790 } 791 } 792 793 /* 794 * So far so good, sync the filesystem once more and 795 * call the VFS unmount code if the sync succeeds. 796 */ 797 if (error == 0) { 798 if (mp->mnt_flag & MNT_RDONLY) { 799 error = VFS_UNMOUNT(mp, flags); 800 } else { 801 error = VFS_SYNC(mp, MNT_WAIT); 802 if ((error == 0) || 803 (error == EOPNOTSUPP) || /* No sync */ 804 (flags & MNT_FORCE)) { 805 error = VFS_UNMOUNT(mp, flags); 806 } 807 } 808 } 809 810 /* 811 * If an error occurred we can still recover, restoring the 812 * syncer vnode and misc flags. 813 */ 814 if (error) { 815 if (mp->mnt_syncer == NULL) 816 vfs_allocate_syncvnode(mp); 817 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 818 mp->mnt_flag |= async_flag; 819 lockmgr(&mp->mnt_lock, LK_RELEASE); 820 if (mp->mnt_kern_flag & MNTK_MWAIT) { 821 mp->mnt_kern_flag &= ~MNTK_MWAIT; 822 wakeup(mp); 823 } 824 goto out; 825 } 826 /* 827 * Clean up any journals still associated with the mount after 828 * filesystem activity has ceased. 829 */ 830 journal_remove_all_journals(mp, 831 ((flags & MNT_FORCE) ? MC_JOURNAL_STOP_IMM : 0)); 832 833 mountlist_remove(mp); 834 835 /* 836 * Remove any installed vnode ops here so the individual VFSs don't 837 * have to. 838 */ 839 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_coherency_ops); 840 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_journal_ops); 841 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_norm_ops); 842 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_spec_ops); 843 vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_fifo_ops); 844 845 if (mp->mnt_ncmountpt.ncp != NULL) { 846 nch = mp->mnt_ncmountpt; 847 cache_zero(&mp->mnt_ncmountpt); 848 cache_clrmountpt(&nch); 849 cache_drop(&nch); 850 } 851 if (mp->mnt_ncmounton.ncp != NULL) { 852 cache_unmounting(mp); 853 nch = mp->mnt_ncmounton; 854 cache_zero(&mp->mnt_ncmounton); 855 cache_clrmountpt(&nch); 856 cache_drop(&nch); 857 } 858 859 mp->mnt_vfc->vfc_refcount--; 860 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) 861 panic("unmount: dangling vnode"); 862 lockmgr(&mp->mnt_lock, LK_RELEASE); 863 if (mp->mnt_kern_flag & MNTK_MWAIT) { 864 mp->mnt_kern_flag &= ~MNTK_MWAIT; 865 wakeup(mp); 866 } 867 868 /* 869 * If we reach here and freeok != 0 we must free the mount. 870 * If refs > 1 cycle and wait, just in case someone tried 871 * to busy the mount after we decided to do the unmount. 872 */ 873 if (freeok) { 874 if (mp->mnt_refs > 1) 875 cache_clearmntcache(); 876 while (mp->mnt_refs > 1) { 877 cache_unmounting(mp); 878 wakeup(mp); 879 tsleep(&mp->mnt_refs, 0, "umntrwait", hz / 10 + 1); 880 cache_clearmntcache(); 881 } 882 lwkt_reltoken(&mp->mnt_token); 883 mount_drop(mp); 884 mp = NULL; 885 } 886 error = 0; 887 KNOTE(&fs_klist, VQ_UNMOUNT); 888 out: 889 if (mp) 890 lwkt_reltoken(&mp->mnt_token); 891 return (error); 892 } 893 894 static 895 void 896 mount_warning(struct mount *mp, const char *ctl, ...) 897 { 898 char *ptr; 899 char *buf; 900 __va_list va; 901 902 __va_start(va, ctl); 903 if (cache_fullpath(NULL, &mp->mnt_ncmounton, NULL, 904 &ptr, &buf, 0) == 0) { 905 kprintf("unmount(%s): ", ptr); 906 kvprintf(ctl, va); 907 kprintf("\n"); 908 kfree(buf, M_TEMP); 909 } else { 910 kprintf("unmount(%p", mp); 911 if (mp->mnt_ncmounton.ncp && mp->mnt_ncmounton.ncp->nc_name) 912 kprintf(",%s", mp->mnt_ncmounton.ncp->nc_name); 913 kprintf("): "); 914 kvprintf(ctl, va); 915 kprintf("\n"); 916 } 917 __va_end(va); 918 } 919 920 /* 921 * Shim cache_fullpath() to handle the case where a process is chrooted into 922 * a subdirectory of a mount. In this case if the root mount matches the 923 * process root directory's mount we have to specify the process's root 924 * directory instead of the mount point, because the mount point might 925 * be above the root directory. 926 */ 927 static 928 int 929 mount_path(struct proc *p, struct mount *mp, char **rb, char **fb) 930 { 931 struct nchandle *nch; 932 933 if (p && p->p_fd->fd_nrdir.mount == mp) 934 nch = &p->p_fd->fd_nrdir; 935 else 936 nch = &mp->mnt_ncmountpt; 937 return(cache_fullpath(p, nch, NULL, rb, fb, 0)); 938 } 939 940 /* 941 * Sync each mounted filesystem. 942 */ 943 944 #ifdef DEBUG 945 static int syncprt = 0; 946 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 947 #endif /* DEBUG */ 948 949 static int sync_callback(struct mount *mp, void *data); 950 951 int 952 sys_sync(struct sync_args *uap) 953 { 954 mountlist_scan(sync_callback, NULL, MNTSCAN_FORWARD); 955 return (0); 956 } 957 958 static 959 int 960 sync_callback(struct mount *mp, void *data __unused) 961 { 962 int asyncflag; 963 964 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 965 asyncflag = mp->mnt_flag & MNT_ASYNC; 966 mp->mnt_flag &= ~MNT_ASYNC; 967 vfs_msync(mp, MNT_NOWAIT); 968 VFS_SYNC(mp, MNT_NOWAIT); 969 mp->mnt_flag |= asyncflag; 970 } 971 return(0); 972 } 973 974 /* XXX PRISON: could be per prison flag */ 975 static int prison_quotas; 976 #if 0 977 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 978 #endif 979 980 /* 981 * quotactl_args(char *path, int fcmd, int uid, caddr_t arg) 982 * 983 * Change filesystem quotas. 984 * 985 * MPALMOSTSAFE 986 */ 987 int 988 sys_quotactl(struct quotactl_args *uap) 989 { 990 struct nlookupdata nd; 991 struct thread *td; 992 struct mount *mp; 993 int error; 994 995 td = curthread; 996 if (td->td_ucred->cr_prison && !prison_quotas) { 997 error = EPERM; 998 goto done; 999 } 1000 1001 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1002 if (error == 0) 1003 error = nlookup(&nd); 1004 if (error == 0) { 1005 mp = nd.nl_nch.mount; 1006 error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, 1007 uap->arg, nd.nl_cred); 1008 } 1009 nlookup_done(&nd); 1010 done: 1011 return (error); 1012 } 1013 1014 /* 1015 * mountctl(char *path, int op, int fd, const void *ctl, int ctllen, 1016 * void *buf, int buflen) 1017 * 1018 * This function operates on a mount point and executes the specified 1019 * operation using the specified control data, and possibly returns data. 1020 * 1021 * The actual number of bytes stored in the result buffer is returned, 0 1022 * if none, otherwise an error is returned. 1023 * 1024 * MPALMOSTSAFE 1025 */ 1026 int 1027 sys_mountctl(struct mountctl_args *uap) 1028 { 1029 struct thread *td = curthread; 1030 struct proc *p = td->td_proc; 1031 struct file *fp; 1032 void *ctl = NULL; 1033 void *buf = NULL; 1034 char *path = NULL; 1035 int error; 1036 1037 /* 1038 * Sanity and permissions checks. We must be root. 1039 */ 1040 KKASSERT(p); 1041 if (td->td_ucred->cr_prison != NULL) 1042 return (EPERM); 1043 if ((uap->op != MOUNTCTL_MOUNTFLAGS) && 1044 (error = priv_check(td, PRIV_ROOT)) != 0) 1045 return (error); 1046 1047 /* 1048 * Argument length checks 1049 */ 1050 if (uap->ctllen < 0 || uap->ctllen > 1024) 1051 return (EINVAL); 1052 if (uap->buflen < 0 || uap->buflen > 16 * 1024) 1053 return (EINVAL); 1054 if (uap->path == NULL) 1055 return (EINVAL); 1056 1057 /* 1058 * Allocate the necessary buffers and copyin data 1059 */ 1060 path = objcache_get(namei_oc, M_WAITOK); 1061 error = copyinstr(uap->path, path, MAXPATHLEN, NULL); 1062 if (error) 1063 goto done; 1064 1065 if (uap->ctllen) { 1066 ctl = kmalloc(uap->ctllen + 1, M_TEMP, M_WAITOK|M_ZERO); 1067 error = copyin(uap->ctl, ctl, uap->ctllen); 1068 if (error) 1069 goto done; 1070 } 1071 if (uap->buflen) 1072 buf = kmalloc(uap->buflen + 1, M_TEMP, M_WAITOK|M_ZERO); 1073 1074 /* 1075 * Validate the descriptor 1076 */ 1077 if (uap->fd >= 0) { 1078 fp = holdfp(p->p_fd, uap->fd, -1); 1079 if (fp == NULL) { 1080 error = EBADF; 1081 goto done; 1082 } 1083 } else { 1084 fp = NULL; 1085 } 1086 1087 /* 1088 * Execute the internal kernel function and clean up. 1089 */ 1090 error = kern_mountctl(path, uap->op, fp, ctl, uap->ctllen, buf, uap->buflen, &uap->sysmsg_result); 1091 if (fp) 1092 fdrop(fp); 1093 if (error == 0 && uap->sysmsg_result > 0) 1094 error = copyout(buf, uap->buf, uap->sysmsg_result); 1095 done: 1096 if (path) 1097 objcache_put(namei_oc, path); 1098 if (ctl) 1099 kfree(ctl, M_TEMP); 1100 if (buf) 1101 kfree(buf, M_TEMP); 1102 return (error); 1103 } 1104 1105 /* 1106 * Execute a mount control operation by resolving the path to a mount point 1107 * and calling vop_mountctl(). 1108 * 1109 * Use the mount point from the nch instead of the vnode so nullfs mounts 1110 * can properly spike the VOP. 1111 */ 1112 int 1113 kern_mountctl(const char *path, int op, struct file *fp, 1114 const void *ctl, int ctllen, 1115 void *buf, int buflen, int *res) 1116 { 1117 struct vnode *vp; 1118 struct nlookupdata nd; 1119 struct nchandle nch; 1120 struct mount *mp; 1121 int error; 1122 1123 *res = 0; 1124 vp = NULL; 1125 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); 1126 if (error) 1127 return (error); 1128 error = nlookup(&nd); 1129 if (error) { 1130 nlookup_done(&nd); 1131 return (error); 1132 } 1133 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 1134 if (error) { 1135 nlookup_done(&nd); 1136 return (error); 1137 } 1138 1139 /* 1140 * Yes, all this is needed to use the nch.mount below, because 1141 * we must maintain a ref on the mount to avoid ripouts (e.g. 1142 * due to heavy mount/unmount use by synth or poudriere). 1143 */ 1144 nch = nd.nl_nch; 1145 cache_zero(&nd.nl_nch); 1146 cache_unlock(&nch); 1147 nlookup_done(&nd); 1148 vn_unlock(vp); 1149 1150 mp = nch.mount; 1151 1152 /* 1153 * Must be the root of the filesystem 1154 */ 1155 if ((vp->v_flag & (VROOT|VPFSROOT)) == 0) { 1156 cache_drop(&nch); 1157 vrele(vp); 1158 return (EINVAL); 1159 } 1160 if (mp == NULL || mp->mnt_kern_flag & MNTK_UNMOUNT) { 1161 kprintf("kern_mountctl: Warning, \"%s\" racing unmount\n", 1162 path); 1163 cache_drop(&nch); 1164 vrele(vp); 1165 return (EINVAL); 1166 } 1167 error = vop_mountctl(mp->mnt_vn_use_ops, vp, op, fp, ctl, ctllen, 1168 buf, buflen, res); 1169 vrele(vp); 1170 cache_drop(&nch); 1171 1172 return (error); 1173 } 1174 1175 int 1176 kern_statfs(struct nlookupdata *nd, struct statfs *buf) 1177 { 1178 struct thread *td = curthread; 1179 struct proc *p = td->td_proc; 1180 struct mount *mp; 1181 struct statfs *sp; 1182 char *fullpath, *freepath; 1183 int error; 1184 1185 if ((error = nlookup(nd)) != 0) 1186 return (error); 1187 mp = nd->nl_nch.mount; 1188 sp = &mp->mnt_stat; 1189 if ((error = VFS_STATFS(mp, sp, nd->nl_cred)) != 0) 1190 return (error); 1191 1192 error = mount_path(p, mp, &fullpath, &freepath); 1193 if (error) 1194 return(error); 1195 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 1196 strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); 1197 kfree(freepath, M_TEMP); 1198 1199 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 1200 bcopy(sp, buf, sizeof(*buf)); 1201 /* Only root should have access to the fsid's. */ 1202 if (priv_check(td, PRIV_ROOT)) 1203 buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; 1204 return (0); 1205 } 1206 1207 /* 1208 * statfs_args(char *path, struct statfs *buf) 1209 * 1210 * Get filesystem statistics. 1211 */ 1212 int 1213 sys_statfs(struct statfs_args *uap) 1214 { 1215 struct nlookupdata nd; 1216 struct statfs buf; 1217 int error; 1218 1219 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1220 if (error == 0) 1221 error = kern_statfs(&nd, &buf); 1222 nlookup_done(&nd); 1223 if (error == 0) 1224 error = copyout(&buf, uap->buf, sizeof(*uap->buf)); 1225 return (error); 1226 } 1227 1228 int 1229 kern_fstatfs(int fd, struct statfs *buf) 1230 { 1231 struct thread *td = curthread; 1232 struct proc *p = td->td_proc; 1233 struct file *fp; 1234 struct mount *mp; 1235 struct statfs *sp; 1236 char *fullpath, *freepath; 1237 int error; 1238 1239 KKASSERT(p); 1240 if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) 1241 return (error); 1242 1243 /* 1244 * Try to use mount info from any overlays rather than the 1245 * mount info for the underlying vnode, otherwise we will 1246 * fail when operating on null-mounted paths inside a chroot. 1247 */ 1248 if ((mp = fp->f_nchandle.mount) == NULL) 1249 mp = ((struct vnode *)fp->f_data)->v_mount; 1250 if (mp == NULL) { 1251 error = EBADF; 1252 goto done; 1253 } 1254 if (fp->f_cred == NULL) { 1255 error = EINVAL; 1256 goto done; 1257 } 1258 sp = &mp->mnt_stat; 1259 if ((error = VFS_STATFS(mp, sp, fp->f_cred)) != 0) 1260 goto done; 1261 1262 if ((error = mount_path(p, mp, &fullpath, &freepath)) != 0) 1263 goto done; 1264 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 1265 strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); 1266 kfree(freepath, M_TEMP); 1267 1268 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 1269 bcopy(sp, buf, sizeof(*buf)); 1270 1271 /* Only root should have access to the fsid's. */ 1272 if (priv_check(td, PRIV_ROOT)) 1273 buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; 1274 error = 0; 1275 done: 1276 fdrop(fp); 1277 return (error); 1278 } 1279 1280 /* 1281 * fstatfs_args(int fd, struct statfs *buf) 1282 * 1283 * Get filesystem statistics. 1284 */ 1285 int 1286 sys_fstatfs(struct fstatfs_args *uap) 1287 { 1288 struct statfs buf; 1289 int error; 1290 1291 error = kern_fstatfs(uap->fd, &buf); 1292 1293 if (error == 0) 1294 error = copyout(&buf, uap->buf, sizeof(*uap->buf)); 1295 return (error); 1296 } 1297 1298 int 1299 kern_statvfs(struct nlookupdata *nd, struct statvfs *buf) 1300 { 1301 struct mount *mp; 1302 struct statvfs *sp; 1303 int error; 1304 1305 if ((error = nlookup(nd)) != 0) 1306 return (error); 1307 mp = nd->nl_nch.mount; 1308 sp = &mp->mnt_vstat; 1309 if ((error = VFS_STATVFS(mp, sp, nd->nl_cred)) != 0) 1310 return (error); 1311 1312 sp->f_flag = 0; 1313 if (mp->mnt_flag & MNT_RDONLY) 1314 sp->f_flag |= ST_RDONLY; 1315 if (mp->mnt_flag & MNT_NOSUID) 1316 sp->f_flag |= ST_NOSUID; 1317 bcopy(sp, buf, sizeof(*buf)); 1318 return (0); 1319 } 1320 1321 /* 1322 * statfs_args(char *path, struct statfs *buf) 1323 * 1324 * Get filesystem statistics. 1325 */ 1326 int 1327 sys_statvfs(struct statvfs_args *uap) 1328 { 1329 struct nlookupdata nd; 1330 struct statvfs buf; 1331 int error; 1332 1333 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1334 if (error == 0) 1335 error = kern_statvfs(&nd, &buf); 1336 nlookup_done(&nd); 1337 if (error == 0) 1338 error = copyout(&buf, uap->buf, sizeof(*uap->buf)); 1339 return (error); 1340 } 1341 1342 int 1343 kern_fstatvfs(int fd, struct statvfs *buf) 1344 { 1345 struct thread *td = curthread; 1346 struct proc *p = td->td_proc; 1347 struct file *fp; 1348 struct mount *mp; 1349 struct statvfs *sp; 1350 int error; 1351 1352 KKASSERT(p); 1353 if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) 1354 return (error); 1355 if ((mp = fp->f_nchandle.mount) == NULL) 1356 mp = ((struct vnode *)fp->f_data)->v_mount; 1357 if (mp == NULL) { 1358 error = EBADF; 1359 goto done; 1360 } 1361 if (fp->f_cred == NULL) { 1362 error = EINVAL; 1363 goto done; 1364 } 1365 sp = &mp->mnt_vstat; 1366 if ((error = VFS_STATVFS(mp, sp, fp->f_cred)) != 0) 1367 goto done; 1368 1369 sp->f_flag = 0; 1370 if (mp->mnt_flag & MNT_RDONLY) 1371 sp->f_flag |= ST_RDONLY; 1372 if (mp->mnt_flag & MNT_NOSUID) 1373 sp->f_flag |= ST_NOSUID; 1374 1375 bcopy(sp, buf, sizeof(*buf)); 1376 error = 0; 1377 done: 1378 fdrop(fp); 1379 return (error); 1380 } 1381 1382 /* 1383 * fstatfs_args(int fd, struct statfs *buf) 1384 * 1385 * Get filesystem statistics. 1386 */ 1387 int 1388 sys_fstatvfs(struct fstatvfs_args *uap) 1389 { 1390 struct statvfs buf; 1391 int error; 1392 1393 error = kern_fstatvfs(uap->fd, &buf); 1394 1395 if (error == 0) 1396 error = copyout(&buf, uap->buf, sizeof(*uap->buf)); 1397 return (error); 1398 } 1399 1400 /* 1401 * getfsstat_args(struct statfs *buf, long bufsize, int flags) 1402 * 1403 * Get statistics on all filesystems. 1404 */ 1405 1406 struct getfsstat_info { 1407 struct statfs *sfsp; 1408 long count; 1409 long maxcount; 1410 int error; 1411 int flags; 1412 struct thread *td; 1413 }; 1414 1415 static int getfsstat_callback(struct mount *, void *); 1416 1417 int 1418 sys_getfsstat(struct getfsstat_args *uap) 1419 { 1420 struct thread *td = curthread; 1421 struct getfsstat_info info; 1422 1423 bzero(&info, sizeof(info)); 1424 1425 info.maxcount = uap->bufsize / sizeof(struct statfs); 1426 info.sfsp = uap->buf; 1427 info.count = 0; 1428 info.flags = uap->flags; 1429 info.td = td; 1430 1431 mountlist_scan(getfsstat_callback, &info, MNTSCAN_FORWARD); 1432 if (info.sfsp && info.count > info.maxcount) 1433 uap->sysmsg_result = info.maxcount; 1434 else 1435 uap->sysmsg_result = info.count; 1436 return (info.error); 1437 } 1438 1439 static int 1440 getfsstat_callback(struct mount *mp, void *data) 1441 { 1442 struct getfsstat_info *info = data; 1443 struct statfs *sp; 1444 char *freepath; 1445 char *fullpath; 1446 int error; 1447 1448 if (info->sfsp && info->count < info->maxcount) { 1449 if (info->td->td_proc && 1450 !chroot_visible_mnt(mp, info->td->td_proc)) { 1451 return(0); 1452 } 1453 sp = &mp->mnt_stat; 1454 1455 /* 1456 * If MNT_NOWAIT or MNT_LAZY is specified, do not 1457 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 1458 * overrides MNT_WAIT. 1459 */ 1460 if (((info->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || 1461 (info->flags & MNT_WAIT)) && 1462 (error = VFS_STATFS(mp, sp, info->td->td_ucred))) { 1463 return(0); 1464 } 1465 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 1466 1467 error = mount_path(info->td->td_proc, mp, &fullpath, &freepath); 1468 if (error) { 1469 info->error = error; 1470 return(-1); 1471 } 1472 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 1473 strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); 1474 kfree(freepath, M_TEMP); 1475 1476 error = copyout(sp, info->sfsp, sizeof(*sp)); 1477 if (error) { 1478 info->error = error; 1479 return (-1); 1480 } 1481 ++info->sfsp; 1482 } 1483 info->count++; 1484 return(0); 1485 } 1486 1487 /* 1488 * getvfsstat_args(struct statfs *buf, struct statvfs *vbuf, 1489 long bufsize, int flags) 1490 * 1491 * Get statistics on all filesystems. 1492 */ 1493 1494 struct getvfsstat_info { 1495 struct statfs *sfsp; 1496 struct statvfs *vsfsp; 1497 long count; 1498 long maxcount; 1499 int error; 1500 int flags; 1501 struct thread *td; 1502 }; 1503 1504 static int getvfsstat_callback(struct mount *, void *); 1505 1506 int 1507 sys_getvfsstat(struct getvfsstat_args *uap) 1508 { 1509 struct thread *td = curthread; 1510 struct getvfsstat_info info; 1511 1512 bzero(&info, sizeof(info)); 1513 1514 info.maxcount = uap->vbufsize / sizeof(struct statvfs); 1515 info.sfsp = uap->buf; 1516 info.vsfsp = uap->vbuf; 1517 info.count = 0; 1518 info.flags = uap->flags; 1519 info.td = td; 1520 1521 mountlist_scan(getvfsstat_callback, &info, MNTSCAN_FORWARD); 1522 if (info.vsfsp && info.count > info.maxcount) 1523 uap->sysmsg_result = info.maxcount; 1524 else 1525 uap->sysmsg_result = info.count; 1526 return (info.error); 1527 } 1528 1529 static int 1530 getvfsstat_callback(struct mount *mp, void *data) 1531 { 1532 struct getvfsstat_info *info = data; 1533 struct statfs *sp; 1534 struct statvfs *vsp; 1535 char *freepath; 1536 char *fullpath; 1537 int error; 1538 1539 if (info->vsfsp && info->count < info->maxcount) { 1540 if (info->td->td_proc && 1541 !chroot_visible_mnt(mp, info->td->td_proc)) { 1542 return(0); 1543 } 1544 sp = &mp->mnt_stat; 1545 vsp = &mp->mnt_vstat; 1546 1547 /* 1548 * If MNT_NOWAIT or MNT_LAZY is specified, do not 1549 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 1550 * overrides MNT_WAIT. 1551 */ 1552 if (((info->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || 1553 (info->flags & MNT_WAIT)) && 1554 (error = VFS_STATFS(mp, sp, info->td->td_ucred))) { 1555 return(0); 1556 } 1557 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 1558 1559 if (((info->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || 1560 (info->flags & MNT_WAIT)) && 1561 (error = VFS_STATVFS(mp, vsp, info->td->td_ucred))) { 1562 return(0); 1563 } 1564 vsp->f_flag = 0; 1565 if (mp->mnt_flag & MNT_RDONLY) 1566 vsp->f_flag |= ST_RDONLY; 1567 if (mp->mnt_flag & MNT_NOSUID) 1568 vsp->f_flag |= ST_NOSUID; 1569 1570 error = mount_path(info->td->td_proc, mp, &fullpath, &freepath); 1571 if (error) { 1572 info->error = error; 1573 return(-1); 1574 } 1575 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 1576 strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); 1577 kfree(freepath, M_TEMP); 1578 1579 error = copyout(sp, info->sfsp, sizeof(*sp)); 1580 if (error == 0) 1581 error = copyout(vsp, info->vsfsp, sizeof(*vsp)); 1582 if (error) { 1583 info->error = error; 1584 return (-1); 1585 } 1586 ++info->sfsp; 1587 ++info->vsfsp; 1588 } 1589 info->count++; 1590 return(0); 1591 } 1592 1593 1594 /* 1595 * fchdir_args(int fd) 1596 * 1597 * Change current working directory to a given file descriptor. 1598 */ 1599 int 1600 sys_fchdir(struct fchdir_args *uap) 1601 { 1602 struct thread *td = curthread; 1603 struct proc *p = td->td_proc; 1604 struct filedesc *fdp = p->p_fd; 1605 struct vnode *vp, *ovp; 1606 struct mount *mp; 1607 struct file *fp; 1608 struct nchandle nch, onch, tnch; 1609 int error; 1610 1611 if ((error = holdvnode(fdp, uap->fd, &fp)) != 0) 1612 return (error); 1613 lwkt_gettoken(&p->p_token); 1614 vp = (struct vnode *)fp->f_data; 1615 vref(vp); 1616 vn_lock(vp, LK_SHARED | LK_RETRY); 1617 if (fp->f_nchandle.ncp == NULL) 1618 error = ENOTDIR; 1619 else 1620 error = checkvp_chdir(vp, td); 1621 if (error) { 1622 vput(vp); 1623 goto done; 1624 } 1625 cache_copy(&fp->f_nchandle, &nch); 1626 1627 /* 1628 * If the ncp has become a mount point, traverse through 1629 * the mount point. 1630 */ 1631 1632 while (!error && (nch.ncp->nc_flag & NCF_ISMOUNTPT) && 1633 (mp = cache_findmount(&nch)) != NULL 1634 ) { 1635 error = nlookup_mp(mp, &tnch); 1636 if (error == 0) { 1637 cache_unlock(&tnch); /* leave ref intact */ 1638 vput(vp); 1639 vp = tnch.ncp->nc_vp; 1640 error = vget(vp, LK_SHARED); 1641 KKASSERT(error == 0); 1642 cache_drop(&nch); 1643 nch = tnch; 1644 } 1645 cache_dropmount(mp); 1646 } 1647 if (error == 0) { 1648 spin_lock(&fdp->fd_spin); 1649 ovp = fdp->fd_cdir; 1650 onch = fdp->fd_ncdir; 1651 fdp->fd_cdir = vp; 1652 fdp->fd_ncdir = nch; 1653 spin_unlock(&fdp->fd_spin); 1654 vn_unlock(vp); /* leave ref intact */ 1655 cache_drop(&onch); 1656 vrele(ovp); 1657 } else { 1658 cache_drop(&nch); 1659 vput(vp); 1660 } 1661 fdrop(fp); 1662 done: 1663 lwkt_reltoken(&p->p_token); 1664 return (error); 1665 } 1666 1667 int 1668 kern_chdir(struct nlookupdata *nd) 1669 { 1670 struct thread *td = curthread; 1671 struct proc *p = td->td_proc; 1672 struct filedesc *fdp = p->p_fd; 1673 struct vnode *vp, *ovp; 1674 struct nchandle onch; 1675 int error; 1676 1677 nd->nl_flags |= NLC_SHAREDLOCK; 1678 if ((error = nlookup(nd)) != 0) 1679 return (error); 1680 if ((vp = nd->nl_nch.ncp->nc_vp) == NULL) 1681 return (ENOENT); 1682 if ((error = vget(vp, LK_SHARED)) != 0) 1683 return (error); 1684 1685 lwkt_gettoken(&p->p_token); 1686 error = checkvp_chdir(vp, td); 1687 vn_unlock(vp); 1688 if (error == 0) { 1689 spin_lock(&fdp->fd_spin); 1690 ovp = fdp->fd_cdir; 1691 onch = fdp->fd_ncdir; 1692 fdp->fd_ncdir = nd->nl_nch; 1693 fdp->fd_cdir = vp; 1694 spin_unlock(&fdp->fd_spin); 1695 cache_unlock(&nd->nl_nch); /* leave reference intact */ 1696 cache_drop(&onch); 1697 vrele(ovp); 1698 cache_zero(&nd->nl_nch); 1699 } else { 1700 vrele(vp); 1701 } 1702 lwkt_reltoken(&p->p_token); 1703 return (error); 1704 } 1705 1706 /* 1707 * chdir_args(char *path) 1708 * 1709 * Change current working directory (``.''). 1710 */ 1711 int 1712 sys_chdir(struct chdir_args *uap) 1713 { 1714 struct nlookupdata nd; 1715 int error; 1716 1717 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1718 if (error == 0) 1719 error = kern_chdir(&nd); 1720 nlookup_done(&nd); 1721 return (error); 1722 } 1723 1724 /* 1725 * Helper function for raised chroot(2) security function: Refuse if 1726 * any filedescriptors are open directories. 1727 */ 1728 static int 1729 chroot_refuse_vdir_fds(struct filedesc *fdp) 1730 { 1731 struct vnode *vp; 1732 struct file *fp; 1733 int error; 1734 int fd; 1735 1736 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 1737 if ((error = holdvnode(fdp, fd, &fp)) != 0) 1738 continue; 1739 vp = (struct vnode *)fp->f_data; 1740 if (vp->v_type != VDIR) { 1741 fdrop(fp); 1742 continue; 1743 } 1744 fdrop(fp); 1745 return(EPERM); 1746 } 1747 return (0); 1748 } 1749 1750 /* 1751 * This sysctl determines if we will allow a process to chroot(2) if it 1752 * has a directory open: 1753 * 0: disallowed for all processes. 1754 * 1: allowed for processes that were not already chroot(2)'ed. 1755 * 2: allowed for all processes. 1756 */ 1757 1758 static int chroot_allow_open_directories = 1; 1759 1760 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 1761 &chroot_allow_open_directories, 0, ""); 1762 1763 /* 1764 * chroot to the specified namecache entry. We obtain the vp from the 1765 * namecache data. The passed ncp must be locked and referenced and will 1766 * remain locked and referenced on return. 1767 */ 1768 int 1769 kern_chroot(struct nchandle *nch) 1770 { 1771 struct thread *td = curthread; 1772 struct proc *p = td->td_proc; 1773 struct filedesc *fdp = p->p_fd; 1774 struct vnode *vp; 1775 int error; 1776 1777 /* 1778 * Only privileged user can chroot 1779 */ 1780 error = priv_check_cred(td->td_ucred, PRIV_VFS_CHROOT, 0); 1781 if (error) 1782 return (error); 1783 1784 /* 1785 * Disallow open directory descriptors (fchdir() breakouts). 1786 */ 1787 if (chroot_allow_open_directories == 0 || 1788 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { 1789 if ((error = chroot_refuse_vdir_fds(fdp)) != 0) 1790 return (error); 1791 } 1792 if ((vp = nch->ncp->nc_vp) == NULL) 1793 return (ENOENT); 1794 1795 if ((error = vget(vp, LK_SHARED)) != 0) 1796 return (error); 1797 1798 /* 1799 * Check the validity of vp as a directory to change to and 1800 * associate it with rdir/jdir. 1801 */ 1802 error = checkvp_chdir(vp, td); 1803 vn_unlock(vp); /* leave reference intact */ 1804 if (error == 0) { 1805 vrele(fdp->fd_rdir); 1806 fdp->fd_rdir = vp; /* reference inherited by fd_rdir */ 1807 cache_drop(&fdp->fd_nrdir); 1808 cache_copy(nch, &fdp->fd_nrdir); 1809 if (fdp->fd_jdir == NULL) { 1810 fdp->fd_jdir = vp; 1811 vref(fdp->fd_jdir); 1812 cache_copy(nch, &fdp->fd_njdir); 1813 } 1814 } else { 1815 vrele(vp); 1816 } 1817 return (error); 1818 } 1819 1820 /* 1821 * chroot_args(char *path) 1822 * 1823 * Change notion of root (``/'') directory. 1824 */ 1825 int 1826 sys_chroot(struct chroot_args *uap) 1827 { 1828 struct thread *td __debugvar = curthread; 1829 struct nlookupdata nd; 1830 int error; 1831 1832 KKASSERT(td->td_proc); 1833 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1834 if (error == 0) { 1835 nd.nl_flags |= NLC_EXEC; 1836 error = nlookup(&nd); 1837 if (error == 0) 1838 error = kern_chroot(&nd.nl_nch); 1839 } 1840 nlookup_done(&nd); 1841 return(error); 1842 } 1843 1844 int 1845 sys_chroot_kernel(struct chroot_kernel_args *uap) 1846 { 1847 struct thread *td = curthread; 1848 struct nlookupdata nd; 1849 struct nchandle *nch; 1850 struct vnode *vp; 1851 int error; 1852 1853 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 1854 if (error) 1855 goto error_nond; 1856 1857 error = nlookup(&nd); 1858 if (error) 1859 goto error_out; 1860 1861 nch = &nd.nl_nch; 1862 1863 error = priv_check_cred(td->td_ucred, PRIV_VFS_CHROOT, 0); 1864 if (error) 1865 goto error_out; 1866 1867 if ((vp = nch->ncp->nc_vp) == NULL) { 1868 error = ENOENT; 1869 goto error_out; 1870 } 1871 1872 if ((error = cache_vref(nch, nd.nl_cred, &vp)) != 0) 1873 goto error_out; 1874 1875 kprintf("chroot_kernel: set new rootnch/rootvnode to %s\n", uap->path); 1876 vfs_cache_setroot(vp, cache_hold(nch)); 1877 1878 error_out: 1879 nlookup_done(&nd); 1880 error_nond: 1881 return(error); 1882 } 1883 1884 /* 1885 * Common routine for chroot and chdir. Given a locked, referenced vnode, 1886 * determine whether it is legal to chdir to the vnode. The vnode's state 1887 * is not changed by this call. 1888 */ 1889 static int 1890 checkvp_chdir(struct vnode *vp, struct thread *td) 1891 { 1892 int error; 1893 1894 if (vp->v_type != VDIR) 1895 error = ENOTDIR; 1896 else 1897 error = VOP_EACCESS(vp, VEXEC, td->td_ucred); 1898 return (error); 1899 } 1900 1901 int 1902 kern_open(struct nlookupdata *nd, int oflags, int mode, int *res) 1903 { 1904 struct thread *td = curthread; 1905 struct proc *p = td->td_proc; 1906 struct lwp *lp = td->td_lwp; 1907 struct filedesc *fdp = p->p_fd; 1908 int cmode, flags; 1909 struct file *nfp; 1910 struct file *fp; 1911 struct vnode *vp; 1912 int type, indx, error = 0; 1913 struct flock lf; 1914 1915 if ((oflags & O_ACCMODE) == O_ACCMODE) 1916 return (EINVAL); 1917 flags = FFLAGS(oflags); 1918 error = falloc(lp, &nfp, NULL); 1919 if (error) 1920 return (error); 1921 fp = nfp; 1922 cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT; 1923 1924 /* 1925 * XXX p_dupfd is a real mess. It allows a device to return a 1926 * file descriptor to be duplicated rather then doing the open 1927 * itself. 1928 */ 1929 lp->lwp_dupfd = -1; 1930 1931 /* 1932 * Call vn_open() to do the lookup and assign the vnode to the 1933 * file pointer. vn_open() does not change the ref count on fp 1934 * and the vnode, on success, will be inherited by the file pointer 1935 * and unlocked. 1936 * 1937 * Request a shared lock on the vnode if possible. 1938 * 1939 * Executable binaries can race VTEXT against O_RDWR opens, so 1940 * use an exclusive lock for O_RDWR opens as well. 1941 * 1942 * NOTE: We need a flag to separate terminal vnode locking from 1943 * parent locking. O_CREAT needs parent locking, but O_TRUNC 1944 * and O_RDWR only need to lock the terminal vnode exclusively. 1945 */ 1946 nd->nl_flags |= NLC_LOCKVP; 1947 if ((flags & (O_CREAT|O_TRUNC|O_RDWR)) == 0) 1948 nd->nl_flags |= NLC_SHAREDLOCK; 1949 1950 error = vn_open(nd, fp, flags, cmode); 1951 nlookup_done(nd); 1952 1953 if (error) { 1954 /* 1955 * handle special fdopen() case. bleh. dupfdopen() is 1956 * responsible for dropping the old contents of ofiles[indx] 1957 * if it succeeds. 1958 * 1959 * Note that fsetfd() will add a ref to fp which represents 1960 * the fd_files[] assignment. We must still drop our 1961 * reference. 1962 */ 1963 if ((error == ENODEV || error == ENXIO) && lp->lwp_dupfd >= 0) { 1964 if (fdalloc(p, 0, &indx) == 0) { 1965 error = dupfdopen(fdp, indx, lp->lwp_dupfd, flags, error); 1966 if (error == 0) { 1967 *res = indx; 1968 fdrop(fp); /* our ref */ 1969 return (0); 1970 } 1971 fsetfd(fdp, NULL, indx); 1972 } 1973 } 1974 fdrop(fp); /* our ref */ 1975 if (error == ERESTART) 1976 error = EINTR; 1977 return (error); 1978 } 1979 1980 /* 1981 * ref the vnode for ourselves so it can't be ripped out from under 1982 * is. XXX need an ND flag to request that the vnode be returned 1983 * anyway. 1984 * 1985 * Reserve a file descriptor but do not assign it until the open 1986 * succeeds. 1987 */ 1988 vp = (struct vnode *)fp->f_data; 1989 vref(vp); 1990 if ((error = fdalloc(p, 0, &indx)) != 0) { 1991 fdrop(fp); 1992 vrele(vp); 1993 return (error); 1994 } 1995 1996 /* 1997 * If no error occurs the vp will have been assigned to the file 1998 * pointer. 1999 */ 2000 lp->lwp_dupfd = 0; 2001 2002 if (flags & (O_EXLOCK | O_SHLOCK)) { 2003 lf.l_whence = SEEK_SET; 2004 lf.l_start = 0; 2005 lf.l_len = 0; 2006 if (flags & O_EXLOCK) 2007 lf.l_type = F_WRLCK; 2008 else 2009 lf.l_type = F_RDLCK; 2010 if (flags & FNONBLOCK) 2011 type = 0; 2012 else 2013 type = F_WAIT; 2014 2015 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 2016 /* 2017 * lock request failed. Clean up the reserved 2018 * descriptor. 2019 */ 2020 vrele(vp); 2021 fsetfd(fdp, NULL, indx); 2022 fdrop(fp); 2023 return (error); 2024 } 2025 atomic_set_int(&fp->f_flag, FHASLOCK); /* race ok */ 2026 } 2027 #if 0 2028 /* 2029 * Assert that all regular file vnodes were created with a object. 2030 */ 2031 KASSERT(vp->v_type != VREG || vp->v_object != NULL, 2032 ("open: regular file has no backing object after vn_open")); 2033 #endif 2034 2035 vrele(vp); 2036 2037 /* 2038 * release our private reference, leaving the one associated with the 2039 * descriptor table intact. 2040 */ 2041 if (oflags & O_CLOEXEC) 2042 fdp->fd_files[indx].fileflags |= UF_EXCLOSE; 2043 fsetfd(fdp, fp, indx); 2044 fdrop(fp); 2045 *res = indx; 2046 return (error); 2047 } 2048 2049 /* 2050 * open_args(char *path, int flags, int mode) 2051 * 2052 * Check permissions, allocate an open file structure, 2053 * and call the device open routine if any. 2054 */ 2055 int 2056 sys_open(struct open_args *uap) 2057 { 2058 struct nlookupdata nd; 2059 int error; 2060 2061 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2062 if (error == 0) { 2063 error = kern_open(&nd, uap->flags, 2064 uap->mode, &uap->sysmsg_result); 2065 } 2066 nlookup_done(&nd); 2067 return (error); 2068 } 2069 2070 /* 2071 * openat_args(int fd, char *path, int flags, int mode) 2072 */ 2073 int 2074 sys_openat(struct openat_args *uap) 2075 { 2076 struct nlookupdata nd; 2077 int error; 2078 struct file *fp; 2079 2080 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 2081 if (error == 0) { 2082 error = kern_open(&nd, uap->flags, uap->mode, 2083 &uap->sysmsg_result); 2084 } 2085 nlookup_done_at(&nd, fp); 2086 return (error); 2087 } 2088 2089 int 2090 kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor) 2091 { 2092 struct thread *td = curthread; 2093 struct proc *p = td->td_proc; 2094 struct vnode *vp; 2095 struct vattr vattr; 2096 int error; 2097 int whiteout = 0; 2098 2099 KKASSERT(p); 2100 2101 VATTR_NULL(&vattr); 2102 vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask; 2103 vattr.va_rmajor = rmajor; 2104 vattr.va_rminor = rminor; 2105 2106 switch (mode & S_IFMT) { 2107 case S_IFMT: /* used by badsect to flag bad sectors */ 2108 error = priv_check_cred(td->td_ucred, PRIV_VFS_MKNOD_BAD, 0); 2109 vattr.va_type = VBAD; 2110 break; 2111 case S_IFCHR: 2112 error = priv_check(td, PRIV_VFS_MKNOD_DEV); 2113 vattr.va_type = VCHR; 2114 break; 2115 case S_IFBLK: 2116 error = priv_check(td, PRIV_VFS_MKNOD_DEV); 2117 vattr.va_type = VBLK; 2118 break; 2119 case S_IFWHT: 2120 error = priv_check_cred(td->td_ucred, PRIV_VFS_MKNOD_WHT, 0); 2121 whiteout = 1; 2122 break; 2123 case S_IFDIR: /* special directories support for HAMMER */ 2124 error = priv_check_cred(td->td_ucred, PRIV_VFS_MKNOD_DIR, 0); 2125 vattr.va_type = VDIR; 2126 break; 2127 default: 2128 error = EINVAL; 2129 break; 2130 } 2131 2132 if (error) 2133 return (error); 2134 2135 bwillinode(1); 2136 nd->nl_flags |= NLC_CREATE | NLC_REFDVP; 2137 if ((error = nlookup(nd)) != 0) 2138 return (error); 2139 if (nd->nl_nch.ncp->nc_vp) 2140 return (EEXIST); 2141 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 2142 return (error); 2143 2144 if (whiteout) { 2145 error = VOP_NWHITEOUT(&nd->nl_nch, nd->nl_dvp, 2146 nd->nl_cred, NAMEI_CREATE); 2147 } else { 2148 vp = NULL; 2149 error = VOP_NMKNOD(&nd->nl_nch, nd->nl_dvp, 2150 &vp, nd->nl_cred, &vattr); 2151 if (error == 0) 2152 vput(vp); 2153 } 2154 return (error); 2155 } 2156 2157 /* 2158 * mknod_args(char *path, int mode, int dev) 2159 * 2160 * Create a special file. 2161 */ 2162 int 2163 sys_mknod(struct mknod_args *uap) 2164 { 2165 struct nlookupdata nd; 2166 int error; 2167 2168 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2169 if (error == 0) { 2170 error = kern_mknod(&nd, uap->mode, 2171 umajor(uap->dev), uminor(uap->dev)); 2172 } 2173 nlookup_done(&nd); 2174 return (error); 2175 } 2176 2177 /* 2178 * mknodat_args(int fd, char *path, mode_t mode, dev_t dev) 2179 * 2180 * Create a special file. The path is relative to the directory associated 2181 * with fd. 2182 */ 2183 int 2184 sys_mknodat(struct mknodat_args *uap) 2185 { 2186 struct nlookupdata nd; 2187 struct file *fp; 2188 int error; 2189 2190 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 2191 if (error == 0) { 2192 error = kern_mknod(&nd, uap->mode, 2193 umajor(uap->dev), uminor(uap->dev)); 2194 } 2195 nlookup_done_at(&nd, fp); 2196 return (error); 2197 } 2198 2199 int 2200 kern_mkfifo(struct nlookupdata *nd, int mode) 2201 { 2202 struct thread *td = curthread; 2203 struct proc *p = td->td_proc; 2204 struct vattr vattr; 2205 struct vnode *vp; 2206 int error; 2207 2208 bwillinode(1); 2209 2210 nd->nl_flags |= NLC_CREATE | NLC_REFDVP; 2211 if ((error = nlookup(nd)) != 0) 2212 return (error); 2213 if (nd->nl_nch.ncp->nc_vp) 2214 return (EEXIST); 2215 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 2216 return (error); 2217 2218 VATTR_NULL(&vattr); 2219 vattr.va_type = VFIFO; 2220 vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask; 2221 vp = NULL; 2222 error = VOP_NMKNOD(&nd->nl_nch, nd->nl_dvp, &vp, nd->nl_cred, &vattr); 2223 if (error == 0) 2224 vput(vp); 2225 return (error); 2226 } 2227 2228 /* 2229 * mkfifo_args(char *path, int mode) 2230 * 2231 * Create a named pipe. 2232 */ 2233 int 2234 sys_mkfifo(struct mkfifo_args *uap) 2235 { 2236 struct nlookupdata nd; 2237 int error; 2238 2239 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2240 if (error == 0) 2241 error = kern_mkfifo(&nd, uap->mode); 2242 nlookup_done(&nd); 2243 return (error); 2244 } 2245 2246 /* 2247 * mkfifoat_args(int fd, char *path, mode_t mode) 2248 * 2249 * Create a named pipe. The path is relative to the directory associated 2250 * with fd. 2251 */ 2252 int 2253 sys_mkfifoat(struct mkfifoat_args *uap) 2254 { 2255 struct nlookupdata nd; 2256 struct file *fp; 2257 int error; 2258 2259 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 2260 if (error == 0) 2261 error = kern_mkfifo(&nd, uap->mode); 2262 nlookup_done_at(&nd, fp); 2263 return (error); 2264 } 2265 2266 static int hardlink_check_uid = 0; 2267 SYSCTL_INT(_security, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, 2268 &hardlink_check_uid, 0, 2269 "Unprivileged processes cannot create hard links to files owned by other " 2270 "users"); 2271 static int hardlink_check_gid = 0; 2272 SYSCTL_INT(_security, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, 2273 &hardlink_check_gid, 0, 2274 "Unprivileged processes cannot create hard links to files owned by other " 2275 "groups"); 2276 2277 static int 2278 can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred) 2279 { 2280 struct vattr va; 2281 int error; 2282 2283 /* 2284 * Shortcut if disabled 2285 */ 2286 if (hardlink_check_uid == 0 && hardlink_check_gid == 0) 2287 return (0); 2288 2289 /* 2290 * Privileged user can always hardlink 2291 */ 2292 if (priv_check_cred(cred, PRIV_VFS_LINK, 0) == 0) 2293 return (0); 2294 2295 /* 2296 * Otherwise only if the originating file is owned by the 2297 * same user or group. Note that any group is allowed if 2298 * the file is owned by the caller. 2299 */ 2300 error = VOP_GETATTR(vp, &va); 2301 if (error != 0) 2302 return (error); 2303 2304 if (hardlink_check_uid) { 2305 if (cred->cr_uid != va.va_uid) 2306 return (EPERM); 2307 } 2308 2309 if (hardlink_check_gid) { 2310 if (cred->cr_uid != va.va_uid && !groupmember(va.va_gid, cred)) 2311 return (EPERM); 2312 } 2313 2314 return (0); 2315 } 2316 2317 int 2318 kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) 2319 { 2320 struct thread *td = curthread; 2321 struct vnode *vp; 2322 int error; 2323 2324 /* 2325 * Lookup the source and obtained a locked vnode. 2326 * 2327 * You may only hardlink a file which you have write permission 2328 * on or which you own. 2329 * 2330 * XXX relookup on vget failure / race ? 2331 */ 2332 bwillinode(1); 2333 nd->nl_flags |= NLC_WRITE | NLC_OWN | NLC_HLINK; 2334 if ((error = nlookup(nd)) != 0) 2335 return (error); 2336 vp = nd->nl_nch.ncp->nc_vp; 2337 KKASSERT(vp != NULL); 2338 if (vp->v_type == VDIR) 2339 return (EPERM); /* POSIX */ 2340 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 2341 return (error); 2342 if ((error = vget(vp, LK_EXCLUSIVE)) != 0) 2343 return (error); 2344 2345 /* 2346 * Unlock the source so we can lookup the target without deadlocking 2347 * (XXX vp is locked already, possible other deadlock?). The target 2348 * must not exist. 2349 */ 2350 KKASSERT(nd->nl_flags & NLC_NCPISLOCKED); 2351 nd->nl_flags &= ~NLC_NCPISLOCKED; 2352 cache_unlock(&nd->nl_nch); 2353 vn_unlock(vp); 2354 2355 linknd->nl_flags |= NLC_CREATE | NLC_REFDVP; 2356 if ((error = nlookup(linknd)) != 0) { 2357 vrele(vp); 2358 return (error); 2359 } 2360 if (linknd->nl_nch.ncp->nc_vp) { 2361 vrele(vp); 2362 return (EEXIST); 2363 } 2364 error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM); 2365 if (error) { 2366 vrele(vp); 2367 return (error); 2368 } 2369 2370 /* 2371 * Finally run the new API VOP. 2372 */ 2373 error = can_hardlink(vp, td, td->td_ucred); 2374 if (error == 0) { 2375 error = VOP_NLINK(&linknd->nl_nch, linknd->nl_dvp, 2376 vp, linknd->nl_cred); 2377 } 2378 vput(vp); 2379 return (error); 2380 } 2381 2382 /* 2383 * link_args(char *path, char *link) 2384 * 2385 * Make a hard file link. 2386 */ 2387 int 2388 sys_link(struct link_args *uap) 2389 { 2390 struct nlookupdata nd, linknd; 2391 int error; 2392 2393 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 2394 if (error == 0) { 2395 error = nlookup_init(&linknd, uap->link, UIO_USERSPACE, 0); 2396 if (error == 0) 2397 error = kern_link(&nd, &linknd); 2398 nlookup_done(&linknd); 2399 } 2400 nlookup_done(&nd); 2401 return (error); 2402 } 2403 2404 /* 2405 * linkat_args(int fd1, char *path1, int fd2, char *path2, int flags) 2406 * 2407 * Make a hard file link. The path1 argument is relative to the directory 2408 * associated with fd1, and similarly the path2 argument is relative to 2409 * the directory associated with fd2. 2410 */ 2411 int 2412 sys_linkat(struct linkat_args *uap) 2413 { 2414 struct nlookupdata nd, linknd; 2415 struct file *fp1, *fp2; 2416 int error; 2417 2418 error = nlookup_init_at(&nd, &fp1, uap->fd1, uap->path1, UIO_USERSPACE, 2419 (uap->flags & AT_SYMLINK_FOLLOW) ? NLC_FOLLOW : 0); 2420 if (error == 0) { 2421 error = nlookup_init_at(&linknd, &fp2, uap->fd2, 2422 uap->path2, UIO_USERSPACE, 0); 2423 if (error == 0) 2424 error = kern_link(&nd, &linknd); 2425 nlookup_done_at(&linknd, fp2); 2426 } 2427 nlookup_done_at(&nd, fp1); 2428 return (error); 2429 } 2430 2431 int 2432 kern_symlink(struct nlookupdata *nd, char *path, int mode) 2433 { 2434 struct vattr vattr; 2435 struct vnode *vp; 2436 struct vnode *dvp; 2437 int error; 2438 2439 bwillinode(1); 2440 nd->nl_flags |= NLC_CREATE | NLC_REFDVP; 2441 if ((error = nlookup(nd)) != 0) 2442 return (error); 2443 if (nd->nl_nch.ncp->nc_vp) 2444 return (EEXIST); 2445 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 2446 return (error); 2447 dvp = nd->nl_dvp; 2448 VATTR_NULL(&vattr); 2449 vattr.va_mode = mode; 2450 error = VOP_NSYMLINK(&nd->nl_nch, dvp, &vp, nd->nl_cred, &vattr, path); 2451 if (error == 0) 2452 vput(vp); 2453 return (error); 2454 } 2455 2456 /* 2457 * symlink(char *path, char *link) 2458 * 2459 * Make a symbolic link. 2460 */ 2461 int 2462 sys_symlink(struct symlink_args *uap) 2463 { 2464 struct thread *td = curthread; 2465 struct nlookupdata nd; 2466 char *path; 2467 int error; 2468 int mode; 2469 2470 path = objcache_get(namei_oc, M_WAITOK); 2471 error = copyinstr(uap->path, path, MAXPATHLEN, NULL); 2472 if (error == 0) { 2473 error = nlookup_init(&nd, uap->link, UIO_USERSPACE, 0); 2474 if (error == 0) { 2475 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask; 2476 error = kern_symlink(&nd, path, mode); 2477 } 2478 nlookup_done(&nd); 2479 } 2480 objcache_put(namei_oc, path); 2481 return (error); 2482 } 2483 2484 /* 2485 * symlinkat_args(char *path1, int fd, char *path2) 2486 * 2487 * Make a symbolic link. The path2 argument is relative to the directory 2488 * associated with fd. 2489 */ 2490 int 2491 sys_symlinkat(struct symlinkat_args *uap) 2492 { 2493 struct thread *td = curthread; 2494 struct nlookupdata nd; 2495 struct file *fp; 2496 char *path1; 2497 int error; 2498 int mode; 2499 2500 path1 = objcache_get(namei_oc, M_WAITOK); 2501 error = copyinstr(uap->path1, path1, MAXPATHLEN, NULL); 2502 if (error == 0) { 2503 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path2, 2504 UIO_USERSPACE, 0); 2505 if (error == 0) { 2506 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask; 2507 error = kern_symlink(&nd, path1, mode); 2508 } 2509 nlookup_done_at(&nd, fp); 2510 } 2511 objcache_put(namei_oc, path1); 2512 return (error); 2513 } 2514 2515 /* 2516 * undelete_args(char *path) 2517 * 2518 * Delete a whiteout from the filesystem. 2519 */ 2520 int 2521 sys_undelete(struct undelete_args *uap) 2522 { 2523 struct nlookupdata nd; 2524 int error; 2525 2526 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2527 bwillinode(1); 2528 nd.nl_flags |= NLC_DELETE | NLC_REFDVP; 2529 if (error == 0) 2530 error = nlookup(&nd); 2531 if (error == 0) 2532 error = ncp_writechk(&nd.nl_nch); 2533 if (error == 0) { 2534 error = VOP_NWHITEOUT(&nd.nl_nch, nd.nl_dvp, nd.nl_cred, 2535 NAMEI_DELETE); 2536 } 2537 nlookup_done(&nd); 2538 return (error); 2539 } 2540 2541 int 2542 kern_unlink(struct nlookupdata *nd) 2543 { 2544 int error; 2545 2546 bwillinode(1); 2547 nd->nl_flags |= NLC_DELETE | NLC_REFDVP; 2548 if ((error = nlookup(nd)) != 0) 2549 return (error); 2550 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 2551 return (error); 2552 error = VOP_NREMOVE(&nd->nl_nch, nd->nl_dvp, nd->nl_cred); 2553 return (error); 2554 } 2555 2556 /* 2557 * unlink_args(char *path) 2558 * 2559 * Delete a name from the filesystem. 2560 */ 2561 int 2562 sys_unlink(struct unlink_args *uap) 2563 { 2564 struct nlookupdata nd; 2565 int error; 2566 2567 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2568 if (error == 0) 2569 error = kern_unlink(&nd); 2570 nlookup_done(&nd); 2571 return (error); 2572 } 2573 2574 2575 /* 2576 * unlinkat_args(int fd, char *path, int flags) 2577 * 2578 * Delete the file or directory entry pointed to by fd/path. 2579 */ 2580 int 2581 sys_unlinkat(struct unlinkat_args *uap) 2582 { 2583 struct nlookupdata nd; 2584 struct file *fp; 2585 int error; 2586 2587 if (uap->flags & ~AT_REMOVEDIR) 2588 return (EINVAL); 2589 2590 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 2591 if (error == 0) { 2592 if (uap->flags & AT_REMOVEDIR) 2593 error = kern_rmdir(&nd); 2594 else 2595 error = kern_unlink(&nd); 2596 } 2597 nlookup_done_at(&nd, fp); 2598 return (error); 2599 } 2600 2601 int 2602 kern_lseek(int fd, off_t offset, int whence, off_t *res) 2603 { 2604 struct thread *td = curthread; 2605 struct proc *p = td->td_proc; 2606 struct file *fp; 2607 struct vnode *vp; 2608 struct vattr vattr; 2609 off_t new_offset; 2610 int error; 2611 2612 fp = holdfp(p->p_fd, fd, -1); 2613 if (fp == NULL) 2614 return (EBADF); 2615 if (fp->f_type != DTYPE_VNODE) { 2616 error = ESPIPE; 2617 goto done; 2618 } 2619 vp = (struct vnode *)fp->f_data; 2620 2621 switch (whence) { 2622 case L_INCR: 2623 spin_lock(&fp->f_spin); 2624 new_offset = fp->f_offset + offset; 2625 error = 0; 2626 break; 2627 case L_XTND: 2628 error = VOP_GETATTR(vp, &vattr); 2629 spin_lock(&fp->f_spin); 2630 new_offset = offset + vattr.va_size; 2631 break; 2632 case L_SET: 2633 new_offset = offset; 2634 error = 0; 2635 spin_lock(&fp->f_spin); 2636 break; 2637 default: 2638 new_offset = 0; 2639 error = EINVAL; 2640 spin_lock(&fp->f_spin); 2641 break; 2642 } 2643 2644 /* 2645 * Validate the seek position. Negative offsets are not allowed 2646 * for regular files or directories. 2647 * 2648 * Normally we would also not want to allow negative offsets for 2649 * character and block-special devices. However kvm addresses 2650 * on 64 bit architectures might appear to be negative and must 2651 * be allowed. 2652 */ 2653 if (error == 0) { 2654 if (new_offset < 0 && 2655 (vp->v_type == VREG || vp->v_type == VDIR)) { 2656 error = EINVAL; 2657 } else { 2658 fp->f_offset = new_offset; 2659 } 2660 } 2661 *res = fp->f_offset; 2662 spin_unlock(&fp->f_spin); 2663 done: 2664 fdrop(fp); 2665 return (error); 2666 } 2667 2668 /* 2669 * lseek_args(int fd, int pad, off_t offset, int whence) 2670 * 2671 * Reposition read/write file offset. 2672 */ 2673 int 2674 sys_lseek(struct lseek_args *uap) 2675 { 2676 int error; 2677 2678 error = kern_lseek(uap->fd, uap->offset, uap->whence, 2679 &uap->sysmsg_offset); 2680 2681 return (error); 2682 } 2683 2684 /* 2685 * Check if current process can access given file. amode is a bitmask of *_OK 2686 * access bits. flags is a bitmask of AT_* flags. 2687 */ 2688 int 2689 kern_access(struct nlookupdata *nd, int amode, int flags) 2690 { 2691 struct vnode *vp; 2692 int error, mode; 2693 2694 if (flags & ~AT_EACCESS) 2695 return (EINVAL); 2696 nd->nl_flags |= NLC_SHAREDLOCK; 2697 if ((error = nlookup(nd)) != 0) 2698 return (error); 2699 retry: 2700 error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_SHARED, &vp); 2701 if (error) 2702 return (error); 2703 2704 /* Flags == 0 means only check for existence. */ 2705 if (amode) { 2706 mode = 0; 2707 if (amode & R_OK) 2708 mode |= VREAD; 2709 if (amode & W_OK) 2710 mode |= VWRITE; 2711 if (amode & X_OK) 2712 mode |= VEXEC; 2713 if ((mode & VWRITE) == 0 || 2714 (error = vn_writechk(vp, &nd->nl_nch)) == 0) 2715 error = VOP_ACCESS_FLAGS(vp, mode, flags, nd->nl_cred); 2716 2717 /* 2718 * If the file handle is stale we have to re-resolve the 2719 * entry with the ncp held exclusively. This is a hack 2720 * at the moment. 2721 */ 2722 if (error == ESTALE) { 2723 vput(vp); 2724 cache_unlock(&nd->nl_nch); 2725 cache_lock(&nd->nl_nch); 2726 cache_setunresolved(&nd->nl_nch); 2727 error = cache_resolve(&nd->nl_nch, nd->nl_cred); 2728 if (error == 0) { 2729 vp = NULL; 2730 goto retry; 2731 } 2732 return(error); 2733 } 2734 } 2735 vput(vp); 2736 return (error); 2737 } 2738 2739 /* 2740 * access_args(char *path, int flags) 2741 * 2742 * Check access permissions. 2743 */ 2744 int 2745 sys_access(struct access_args *uap) 2746 { 2747 struct nlookupdata nd; 2748 int error; 2749 2750 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 2751 if (error == 0) 2752 error = kern_access(&nd, uap->flags, 0); 2753 nlookup_done(&nd); 2754 return (error); 2755 } 2756 2757 2758 /* 2759 * eaccess_args(char *path, int flags) 2760 * 2761 * Check access permissions. 2762 */ 2763 int 2764 sys_eaccess(struct eaccess_args *uap) 2765 { 2766 struct nlookupdata nd; 2767 int error; 2768 2769 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 2770 if (error == 0) 2771 error = kern_access(&nd, uap->flags, AT_EACCESS); 2772 nlookup_done(&nd); 2773 return (error); 2774 } 2775 2776 2777 /* 2778 * faccessat_args(int fd, char *path, int amode, int flags) 2779 * 2780 * Check access permissions. 2781 */ 2782 int 2783 sys_faccessat(struct faccessat_args *uap) 2784 { 2785 struct nlookupdata nd; 2786 struct file *fp; 2787 int error; 2788 2789 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 2790 NLC_FOLLOW); 2791 if (error == 0) 2792 error = kern_access(&nd, uap->amode, uap->flags); 2793 nlookup_done_at(&nd, fp); 2794 return (error); 2795 } 2796 2797 int 2798 kern_stat(struct nlookupdata *nd, struct stat *st) 2799 { 2800 int error; 2801 struct vnode *vp; 2802 2803 nd->nl_flags |= NLC_SHAREDLOCK; 2804 if ((error = nlookup(nd)) != 0) 2805 return (error); 2806 again: 2807 if ((vp = nd->nl_nch.ncp->nc_vp) == NULL) 2808 return (ENOENT); 2809 2810 if ((error = vget(vp, LK_SHARED)) != 0) 2811 return (error); 2812 error = vn_stat(vp, st, nd->nl_cred); 2813 2814 /* 2815 * If the file handle is stale we have to re-resolve the 2816 * entry with the ncp held exclusively. This is a hack 2817 * at the moment. 2818 */ 2819 if (error == ESTALE) { 2820 vput(vp); 2821 cache_unlock(&nd->nl_nch); 2822 cache_lock(&nd->nl_nch); 2823 cache_setunresolved(&nd->nl_nch); 2824 error = cache_resolve(&nd->nl_nch, nd->nl_cred); 2825 if (error == 0) 2826 goto again; 2827 } else { 2828 vput(vp); 2829 } 2830 return (error); 2831 } 2832 2833 /* 2834 * stat_args(char *path, struct stat *ub) 2835 * 2836 * Get file status; this version follows links. 2837 */ 2838 int 2839 sys_stat(struct stat_args *uap) 2840 { 2841 struct nlookupdata nd; 2842 struct stat st; 2843 int error; 2844 2845 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 2846 if (error == 0) { 2847 error = kern_stat(&nd, &st); 2848 if (error == 0) 2849 error = copyout(&st, uap->ub, sizeof(*uap->ub)); 2850 } 2851 nlookup_done(&nd); 2852 return (error); 2853 } 2854 2855 /* 2856 * lstat_args(char *path, struct stat *ub) 2857 * 2858 * Get file status; this version does not follow links. 2859 */ 2860 int 2861 sys_lstat(struct lstat_args *uap) 2862 { 2863 struct nlookupdata nd; 2864 struct stat st; 2865 int error; 2866 2867 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 2868 if (error == 0) { 2869 error = kern_stat(&nd, &st); 2870 if (error == 0) 2871 error = copyout(&st, uap->ub, sizeof(*uap->ub)); 2872 } 2873 nlookup_done(&nd); 2874 return (error); 2875 } 2876 2877 /* 2878 * fstatat_args(int fd, char *path, struct stat *sb, int flags) 2879 * 2880 * Get status of file pointed to by fd/path. 2881 */ 2882 int 2883 sys_fstatat(struct fstatat_args *uap) 2884 { 2885 struct nlookupdata nd; 2886 struct stat st; 2887 int error; 2888 int flags; 2889 struct file *fp; 2890 2891 if (uap->flags & ~AT_SYMLINK_NOFOLLOW) 2892 return (EINVAL); 2893 2894 flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; 2895 2896 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, 2897 UIO_USERSPACE, flags); 2898 if (error == 0) { 2899 error = kern_stat(&nd, &st); 2900 if (error == 0) 2901 error = copyout(&st, uap->sb, sizeof(*uap->sb)); 2902 } 2903 nlookup_done_at(&nd, fp); 2904 return (error); 2905 } 2906 2907 static int 2908 kern_pathconf(char *path, int name, int flags, register_t *sysmsg_regp) 2909 { 2910 struct nlookupdata nd; 2911 struct vnode *vp; 2912 int error; 2913 2914 vp = NULL; 2915 error = nlookup_init(&nd, path, UIO_USERSPACE, flags); 2916 if (error == 0) 2917 error = nlookup(&nd); 2918 if (error == 0) 2919 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 2920 nlookup_done(&nd); 2921 if (error == 0) { 2922 error = VOP_PATHCONF(vp, name, sysmsg_regp); 2923 vput(vp); 2924 } 2925 return (error); 2926 } 2927 2928 /* 2929 * pathconf_Args(char *path, int name) 2930 * 2931 * Get configurable pathname variables. 2932 */ 2933 int 2934 sys_pathconf(struct pathconf_args *uap) 2935 { 2936 return (kern_pathconf(uap->path, uap->name, NLC_FOLLOW, 2937 &uap->sysmsg_reg)); 2938 } 2939 2940 /* 2941 * lpathconf_Args(char *path, int name) 2942 * 2943 * Get configurable pathname variables, but don't follow symlinks. 2944 */ 2945 int 2946 sys_lpathconf(struct lpathconf_args *uap) 2947 { 2948 return (kern_pathconf(uap->path, uap->name, 0, &uap->sysmsg_reg)); 2949 } 2950 2951 /* 2952 * XXX: daver 2953 * kern_readlink isn't properly split yet. There is a copyin burried 2954 * in VOP_READLINK(). 2955 */ 2956 int 2957 kern_readlink(struct nlookupdata *nd, char *buf, int count, int *res) 2958 { 2959 struct thread *td = curthread; 2960 struct vnode *vp; 2961 struct iovec aiov; 2962 struct uio auio; 2963 int error; 2964 2965 nd->nl_flags |= NLC_SHAREDLOCK; 2966 if ((error = nlookup(nd)) != 0) 2967 return (error); 2968 error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_SHARED, &vp); 2969 if (error) 2970 return (error); 2971 if (vp->v_type != VLNK) { 2972 error = EINVAL; 2973 } else { 2974 aiov.iov_base = buf; 2975 aiov.iov_len = count; 2976 auio.uio_iov = &aiov; 2977 auio.uio_iovcnt = 1; 2978 auio.uio_offset = 0; 2979 auio.uio_rw = UIO_READ; 2980 auio.uio_segflg = UIO_USERSPACE; 2981 auio.uio_td = td; 2982 auio.uio_resid = count; 2983 error = VOP_READLINK(vp, &auio, td->td_ucred); 2984 } 2985 vput(vp); 2986 *res = count - auio.uio_resid; 2987 return (error); 2988 } 2989 2990 /* 2991 * readlink_args(char *path, char *buf, int count) 2992 * 2993 * Return target name of a symbolic link. 2994 */ 2995 int 2996 sys_readlink(struct readlink_args *uap) 2997 { 2998 struct nlookupdata nd; 2999 int error; 3000 3001 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 3002 if (error == 0) { 3003 error = kern_readlink(&nd, uap->buf, uap->count, 3004 &uap->sysmsg_result); 3005 } 3006 nlookup_done(&nd); 3007 return (error); 3008 } 3009 3010 /* 3011 * readlinkat_args(int fd, char *path, char *buf, size_t bufsize) 3012 * 3013 * Return target name of a symbolic link. The path is relative to the 3014 * directory associated with fd. 3015 */ 3016 int 3017 sys_readlinkat(struct readlinkat_args *uap) 3018 { 3019 struct nlookupdata nd; 3020 struct file *fp; 3021 int error; 3022 3023 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 3024 if (error == 0) { 3025 error = kern_readlink(&nd, uap->buf, uap->bufsize, 3026 &uap->sysmsg_result); 3027 } 3028 nlookup_done_at(&nd, fp); 3029 return (error); 3030 } 3031 3032 static int 3033 setfflags(struct vnode *vp, int flags) 3034 { 3035 struct thread *td = curthread; 3036 int error; 3037 struct vattr vattr; 3038 3039 /* 3040 * Prevent non-root users from setting flags on devices. When 3041 * a device is reused, users can retain ownership of the device 3042 * if they are allowed to set flags and programs assume that 3043 * chown can't fail when done as root. 3044 */ 3045 if ((vp->v_type == VCHR || vp->v_type == VBLK) && 3046 ((error = priv_check_cred(td->td_ucred, PRIV_VFS_CHFLAGS_DEV, 0)) != 0)) 3047 return (error); 3048 3049 /* 3050 * note: vget is required for any operation that might mod the vnode 3051 * so VINACTIVE is properly cleared. 3052 */ 3053 if ((error = vget(vp, LK_EXCLUSIVE)) == 0) { 3054 VATTR_NULL(&vattr); 3055 vattr.va_flags = flags; 3056 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3057 vput(vp); 3058 } 3059 return (error); 3060 } 3061 3062 /* 3063 * chflags(char *path, int flags) 3064 * 3065 * Change flags of a file given a path name. 3066 */ 3067 int 3068 sys_chflags(struct chflags_args *uap) 3069 { 3070 struct nlookupdata nd; 3071 struct vnode *vp; 3072 int error; 3073 3074 vp = NULL; 3075 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 3076 if (error == 0) 3077 error = nlookup(&nd); 3078 if (error == 0) 3079 error = ncp_writechk(&nd.nl_nch); 3080 if (error == 0) 3081 error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); 3082 nlookup_done(&nd); 3083 if (error == 0) { 3084 error = setfflags(vp, uap->flags); 3085 vrele(vp); 3086 } 3087 return (error); 3088 } 3089 3090 /* 3091 * lchflags(char *path, int flags) 3092 * 3093 * Change flags of a file given a path name, but don't follow symlinks. 3094 */ 3095 int 3096 sys_lchflags(struct lchflags_args *uap) 3097 { 3098 struct nlookupdata nd; 3099 struct vnode *vp; 3100 int error; 3101 3102 vp = NULL; 3103 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 3104 if (error == 0) 3105 error = nlookup(&nd); 3106 if (error == 0) 3107 error = ncp_writechk(&nd.nl_nch); 3108 if (error == 0) 3109 error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); 3110 nlookup_done(&nd); 3111 if (error == 0) { 3112 error = setfflags(vp, uap->flags); 3113 vrele(vp); 3114 } 3115 return (error); 3116 } 3117 3118 /* 3119 * fchflags_args(int fd, int flags) 3120 * 3121 * Change flags of a file given a file descriptor. 3122 */ 3123 int 3124 sys_fchflags(struct fchflags_args *uap) 3125 { 3126 struct thread *td = curthread; 3127 struct proc *p = td->td_proc; 3128 struct file *fp; 3129 int error; 3130 3131 if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) 3132 return (error); 3133 if (fp->f_nchandle.ncp) 3134 error = ncp_writechk(&fp->f_nchandle); 3135 if (error == 0) 3136 error = setfflags((struct vnode *) fp->f_data, uap->flags); 3137 fdrop(fp); 3138 return (error); 3139 } 3140 3141 /* 3142 * chflagsat_args(int fd, const char *path, int flags, int atflags) 3143 * change flags given a pathname relative to a filedescriptor 3144 */ 3145 int sys_chflagsat(struct chflagsat_args *uap) 3146 { 3147 struct nlookupdata nd; 3148 struct vnode *vp; 3149 struct file *fp; 3150 int error; 3151 int lookupflags; 3152 3153 if (uap->atflags & ~AT_SYMLINK_NOFOLLOW) 3154 return (EINVAL); 3155 3156 lookupflags = (uap->atflags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; 3157 3158 vp = NULL; 3159 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, lookupflags); 3160 if (error == 0) 3161 error = nlookup(&nd); 3162 if (error == 0) 3163 error = ncp_writechk(&nd.nl_nch); 3164 if (error == 0) 3165 error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); 3166 nlookup_done_at(&nd, fp); 3167 if (error == 0) { 3168 error = setfflags(vp, uap->flags); 3169 vrele(vp); 3170 } 3171 return (error); 3172 } 3173 3174 3175 static int 3176 setfmode(struct vnode *vp, int mode) 3177 { 3178 struct thread *td = curthread; 3179 int error; 3180 struct vattr vattr; 3181 3182 /* 3183 * note: vget is required for any operation that might mod the vnode 3184 * so VINACTIVE is properly cleared. 3185 */ 3186 if ((error = vget(vp, LK_EXCLUSIVE)) == 0) { 3187 VATTR_NULL(&vattr); 3188 vattr.va_mode = mode & ALLPERMS; 3189 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3190 cache_inval_wxok(vp); 3191 vput(vp); 3192 } 3193 return error; 3194 } 3195 3196 int 3197 kern_chmod(struct nlookupdata *nd, int mode) 3198 { 3199 struct vnode *vp; 3200 int error; 3201 3202 if ((error = nlookup(nd)) != 0) 3203 return (error); 3204 if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) 3205 return (error); 3206 if ((error = ncp_writechk(&nd->nl_nch)) == 0) 3207 error = setfmode(vp, mode); 3208 vrele(vp); 3209 return (error); 3210 } 3211 3212 /* 3213 * chmod_args(char *path, int mode) 3214 * 3215 * Change mode of a file given path name. 3216 */ 3217 int 3218 sys_chmod(struct chmod_args *uap) 3219 { 3220 struct nlookupdata nd; 3221 int error; 3222 3223 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 3224 if (error == 0) 3225 error = kern_chmod(&nd, uap->mode); 3226 nlookup_done(&nd); 3227 return (error); 3228 } 3229 3230 /* 3231 * lchmod_args(char *path, int mode) 3232 * 3233 * Change mode of a file given path name (don't follow links.) 3234 */ 3235 int 3236 sys_lchmod(struct lchmod_args *uap) 3237 { 3238 struct nlookupdata nd; 3239 int error; 3240 3241 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 3242 if (error == 0) 3243 error = kern_chmod(&nd, uap->mode); 3244 nlookup_done(&nd); 3245 return (error); 3246 } 3247 3248 /* 3249 * fchmod_args(int fd, int mode) 3250 * 3251 * Change mode of a file given a file descriptor. 3252 */ 3253 int 3254 sys_fchmod(struct fchmod_args *uap) 3255 { 3256 struct thread *td = curthread; 3257 struct proc *p = td->td_proc; 3258 struct file *fp; 3259 int error; 3260 3261 if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) 3262 return (error); 3263 if (fp->f_nchandle.ncp) 3264 error = ncp_writechk(&fp->f_nchandle); 3265 if (error == 0) 3266 error = setfmode((struct vnode *)fp->f_data, uap->mode); 3267 fdrop(fp); 3268 return (error); 3269 } 3270 3271 /* 3272 * fchmodat_args(char *path, int mode) 3273 * 3274 * Change mode of a file pointed to by fd/path. 3275 */ 3276 int 3277 sys_fchmodat(struct fchmodat_args *uap) 3278 { 3279 struct nlookupdata nd; 3280 struct file *fp; 3281 int error; 3282 int flags; 3283 3284 if (uap->flags & ~AT_SYMLINK_NOFOLLOW) 3285 return (EINVAL); 3286 flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; 3287 3288 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, 3289 UIO_USERSPACE, flags); 3290 if (error == 0) 3291 error = kern_chmod(&nd, uap->mode); 3292 nlookup_done_at(&nd, fp); 3293 return (error); 3294 } 3295 3296 static int 3297 setfown(struct mount *mp, struct vnode *vp, uid_t uid, gid_t gid) 3298 { 3299 struct thread *td = curthread; 3300 int error; 3301 struct vattr vattr; 3302 uid_t o_uid; 3303 gid_t o_gid; 3304 uint64_t size; 3305 3306 /* 3307 * note: vget is required for any operation that might mod the vnode 3308 * so VINACTIVE is properly cleared. 3309 */ 3310 if ((error = vget(vp, LK_EXCLUSIVE)) == 0) { 3311 if ((error = VOP_GETATTR(vp, &vattr)) != 0) 3312 return error; 3313 o_uid = vattr.va_uid; 3314 o_gid = vattr.va_gid; 3315 size = vattr.va_size; 3316 3317 VATTR_NULL(&vattr); 3318 vattr.va_uid = uid; 3319 vattr.va_gid = gid; 3320 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3321 vput(vp); 3322 } 3323 3324 if (error == 0) { 3325 if (uid == -1) 3326 uid = o_uid; 3327 if (gid == -1) 3328 gid = o_gid; 3329 VFS_ACCOUNT(mp, o_uid, o_gid, -size); 3330 VFS_ACCOUNT(mp, uid, gid, size); 3331 } 3332 3333 return error; 3334 } 3335 3336 int 3337 kern_chown(struct nlookupdata *nd, int uid, int gid) 3338 { 3339 struct vnode *vp; 3340 int error; 3341 3342 if ((error = nlookup(nd)) != 0) 3343 return (error); 3344 if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) 3345 return (error); 3346 if ((error = ncp_writechk(&nd->nl_nch)) == 0) 3347 error = setfown(nd->nl_nch.mount, vp, uid, gid); 3348 vrele(vp); 3349 return (error); 3350 } 3351 3352 /* 3353 * chown(char *path, int uid, int gid) 3354 * 3355 * Set ownership given a path name. 3356 */ 3357 int 3358 sys_chown(struct chown_args *uap) 3359 { 3360 struct nlookupdata nd; 3361 int error; 3362 3363 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 3364 if (error == 0) 3365 error = kern_chown(&nd, uap->uid, uap->gid); 3366 nlookup_done(&nd); 3367 return (error); 3368 } 3369 3370 /* 3371 * lchown_args(char *path, int uid, int gid) 3372 * 3373 * Set ownership given a path name, do not cross symlinks. 3374 */ 3375 int 3376 sys_lchown(struct lchown_args *uap) 3377 { 3378 struct nlookupdata nd; 3379 int error; 3380 3381 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 3382 if (error == 0) 3383 error = kern_chown(&nd, uap->uid, uap->gid); 3384 nlookup_done(&nd); 3385 return (error); 3386 } 3387 3388 /* 3389 * fchown_args(int fd, int uid, int gid) 3390 * 3391 * Set ownership given a file descriptor. 3392 */ 3393 int 3394 sys_fchown(struct fchown_args *uap) 3395 { 3396 struct thread *td = curthread; 3397 struct proc *p = td->td_proc; 3398 struct file *fp; 3399 int error; 3400 3401 if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) 3402 return (error); 3403 if (fp->f_nchandle.ncp) 3404 error = ncp_writechk(&fp->f_nchandle); 3405 if (error == 0) 3406 error = setfown(p->p_fd->fd_ncdir.mount, 3407 (struct vnode *)fp->f_data, uap->uid, uap->gid); 3408 fdrop(fp); 3409 return (error); 3410 } 3411 3412 /* 3413 * fchownat(int fd, char *path, int uid, int gid, int flags) 3414 * 3415 * Set ownership of file pointed to by fd/path. 3416 */ 3417 int 3418 sys_fchownat(struct fchownat_args *uap) 3419 { 3420 struct nlookupdata nd; 3421 struct file *fp; 3422 int error; 3423 int flags; 3424 3425 if (uap->flags & ~AT_SYMLINK_NOFOLLOW) 3426 return (EINVAL); 3427 flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; 3428 3429 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, 3430 UIO_USERSPACE, flags); 3431 if (error == 0) 3432 error = kern_chown(&nd, uap->uid, uap->gid); 3433 nlookup_done_at(&nd, fp); 3434 return (error); 3435 } 3436 3437 3438 static int 3439 getutimes(struct timeval *tvp, struct timespec *tsp) 3440 { 3441 struct timeval tv[2]; 3442 int error; 3443 3444 if (tvp == NULL) { 3445 microtime(&tv[0]); 3446 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 3447 tsp[1] = tsp[0]; 3448 } else { 3449 if ((error = itimerfix(tvp)) != 0) 3450 return (error); 3451 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 3452 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 3453 } 3454 return 0; 3455 } 3456 3457 static int 3458 getutimens(const struct timespec *ts, struct timespec *newts, int *nullflag) 3459 { 3460 struct timespec tsnow; 3461 int error; 3462 3463 *nullflag = 0; 3464 nanotime(&tsnow); 3465 if (ts == NULL) { 3466 newts[0] = tsnow; 3467 newts[1] = tsnow; 3468 *nullflag = 1; 3469 return (0); 3470 } 3471 3472 newts[0] = ts[0]; 3473 newts[1] = ts[1]; 3474 if (newts[0].tv_nsec == UTIME_OMIT && newts[1].tv_nsec == UTIME_OMIT) 3475 return (0); 3476 if (newts[0].tv_nsec == UTIME_NOW && newts[1].tv_nsec == UTIME_NOW) 3477 *nullflag = 1; 3478 3479 if (newts[0].tv_nsec == UTIME_OMIT) 3480 newts[0].tv_sec = VNOVAL; 3481 else if (newts[0].tv_nsec == UTIME_NOW) 3482 newts[0] = tsnow; 3483 else if ((error = itimespecfix(&newts[0])) != 0) 3484 return (error); 3485 3486 if (newts[1].tv_nsec == UTIME_OMIT) 3487 newts[1].tv_sec = VNOVAL; 3488 else if (newts[1].tv_nsec == UTIME_NOW) 3489 newts[1] = tsnow; 3490 else if ((error = itimespecfix(&newts[1])) != 0) 3491 return (error); 3492 3493 return (0); 3494 } 3495 3496 static int 3497 setutimes(struct vnode *vp, struct vattr *vattr, 3498 const struct timespec *ts, int nullflag) 3499 { 3500 struct thread *td = curthread; 3501 int error; 3502 3503 VATTR_NULL(vattr); 3504 vattr->va_atime = ts[0]; 3505 vattr->va_mtime = ts[1]; 3506 if (nullflag) 3507 vattr->va_vaflags |= VA_UTIMES_NULL; 3508 error = VOP_SETATTR(vp, vattr, td->td_ucred); 3509 3510 return error; 3511 } 3512 3513 int 3514 kern_utimes(struct nlookupdata *nd, struct timeval *tptr) 3515 { 3516 struct timespec ts[2]; 3517 int error; 3518 3519 if (tptr) { 3520 if ((error = getutimes(tptr, ts)) != 0) 3521 return (error); 3522 } 3523 error = kern_utimensat(nd, tptr ? ts : NULL, 0); 3524 return (error); 3525 } 3526 3527 /* 3528 * utimes_args(char *path, struct timeval *tptr) 3529 * 3530 * Set the access and modification times of a file. 3531 */ 3532 int 3533 sys_utimes(struct utimes_args *uap) 3534 { 3535 struct timeval tv[2]; 3536 struct nlookupdata nd; 3537 int error; 3538 3539 if (uap->tptr) { 3540 error = copyin(uap->tptr, tv, sizeof(tv)); 3541 if (error) 3542 return (error); 3543 } 3544 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 3545 if (error == 0) 3546 error = kern_utimes(&nd, uap->tptr ? tv : NULL); 3547 nlookup_done(&nd); 3548 return (error); 3549 } 3550 3551 /* 3552 * lutimes_args(char *path, struct timeval *tptr) 3553 * 3554 * Set the access and modification times of a file. 3555 */ 3556 int 3557 sys_lutimes(struct lutimes_args *uap) 3558 { 3559 struct timeval tv[2]; 3560 struct nlookupdata nd; 3561 int error; 3562 3563 if (uap->tptr) { 3564 error = copyin(uap->tptr, tv, sizeof(tv)); 3565 if (error) 3566 return (error); 3567 } 3568 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 3569 if (error == 0) 3570 error = kern_utimes(&nd, uap->tptr ? tv : NULL); 3571 nlookup_done(&nd); 3572 return (error); 3573 } 3574 3575 /* 3576 * Set utimes on a file descriptor. The creds used to open the 3577 * file are used to determine whether the operation is allowed 3578 * or not. 3579 */ 3580 int 3581 kern_futimens(int fd, struct timespec *ts) 3582 { 3583 struct thread *td = curthread; 3584 struct proc *p = td->td_proc; 3585 struct timespec newts[2]; 3586 struct file *fp; 3587 struct vnode *vp; 3588 struct vattr vattr; 3589 int nullflag; 3590 int error; 3591 3592 error = getutimens(ts, newts, &nullflag); 3593 if (error) 3594 return (error); 3595 if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) 3596 return (error); 3597 if (fp->f_nchandle.ncp) 3598 error = ncp_writechk(&fp->f_nchandle); 3599 if (error == 0) { 3600 vp = fp->f_data; 3601 error = vget(vp, LK_EXCLUSIVE); 3602 if (error == 0) { 3603 error = VOP_GETATTR(vp, &vattr); 3604 if (error == 0) { 3605 error = naccess_va(&vattr, NLC_OWN | NLC_WRITE, 3606 fp->f_cred); 3607 } 3608 if (error == 0) { 3609 error = setutimes(vp, &vattr, newts, nullflag); 3610 } 3611 vput(vp); 3612 } 3613 } 3614 fdrop(fp); 3615 return (error); 3616 } 3617 3618 /* 3619 * futimens_args(int fd, struct timespec *ts) 3620 * 3621 * Set the access and modification times of a file. 3622 */ 3623 int 3624 sys_futimens(struct futimens_args *uap) 3625 { 3626 struct timespec ts[2]; 3627 int error; 3628 3629 if (uap->ts) { 3630 error = copyin(uap->ts, ts, sizeof(ts)); 3631 if (error) 3632 return (error); 3633 } 3634 error = kern_futimens(uap->fd, uap->ts ? ts : NULL); 3635 return (error); 3636 } 3637 3638 int 3639 kern_futimes(int fd, struct timeval *tptr) 3640 { 3641 struct timespec ts[2]; 3642 int error; 3643 3644 if (tptr) { 3645 if ((error = getutimes(tptr, ts)) != 0) 3646 return (error); 3647 } 3648 error = kern_futimens(fd, tptr ? ts : NULL); 3649 return (error); 3650 } 3651 3652 /* 3653 * futimes_args(int fd, struct timeval *tptr) 3654 * 3655 * Set the access and modification times of a file. 3656 */ 3657 int 3658 sys_futimes(struct futimes_args *uap) 3659 { 3660 struct timeval tv[2]; 3661 int error; 3662 3663 if (uap->tptr) { 3664 error = copyin(uap->tptr, tv, sizeof(tv)); 3665 if (error) 3666 return (error); 3667 } 3668 error = kern_futimes(uap->fd, uap->tptr ? tv : NULL); 3669 return (error); 3670 } 3671 3672 int 3673 kern_utimensat(struct nlookupdata *nd, const struct timespec *ts, int flags) 3674 { 3675 struct timespec newts[2]; 3676 struct vnode *vp; 3677 struct vattr vattr; 3678 int nullflag; 3679 int error; 3680 3681 if (flags & ~AT_SYMLINK_NOFOLLOW) 3682 return (EINVAL); 3683 3684 error = getutimens(ts, newts, &nullflag); 3685 if (error) 3686 return (error); 3687 3688 nd->nl_flags |= NLC_OWN | NLC_WRITE; 3689 if ((error = nlookup(nd)) != 0) 3690 return (error); 3691 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 3692 return (error); 3693 if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) 3694 return (error); 3695 if ((error = vn_writechk(vp, &nd->nl_nch)) == 0) { 3696 error = vget(vp, LK_EXCLUSIVE); 3697 if (error == 0) { 3698 error = setutimes(vp, &vattr, newts, nullflag); 3699 vput(vp); 3700 } 3701 } 3702 vrele(vp); 3703 return (error); 3704 } 3705 3706 /* 3707 * utimensat_args(int fd, const char *path, const struct timespec *ts, int flags); 3708 * 3709 * Set file access and modification times of a file. 3710 */ 3711 int 3712 sys_utimensat(struct utimensat_args *uap) 3713 { 3714 struct timespec ts[2]; 3715 struct nlookupdata nd; 3716 struct file *fp; 3717 int error; 3718 int flags; 3719 3720 if (uap->ts) { 3721 error = copyin(uap->ts, ts, sizeof(ts)); 3722 if (error) 3723 return (error); 3724 } 3725 3726 flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW; 3727 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, 3728 UIO_USERSPACE, flags); 3729 if (error == 0) 3730 error = kern_utimensat(&nd, uap->ts ? ts : NULL, uap->flags); 3731 nlookup_done_at(&nd, fp); 3732 return (error); 3733 } 3734 3735 int 3736 kern_truncate(struct nlookupdata *nd, off_t length) 3737 { 3738 struct vnode *vp; 3739 struct vattr vattr; 3740 int error; 3741 uid_t uid = 0; 3742 gid_t gid = 0; 3743 uint64_t old_size = 0; 3744 3745 if (length < 0) 3746 return(EINVAL); 3747 nd->nl_flags |= NLC_WRITE | NLC_TRUNCATE; 3748 if ((error = nlookup(nd)) != 0) 3749 return (error); 3750 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 3751 return (error); 3752 if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) 3753 return (error); 3754 error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM); 3755 if (error) { 3756 vrele(vp); 3757 return (error); 3758 } 3759 if (vp->v_type == VDIR) { 3760 error = EISDIR; 3761 goto done; 3762 } 3763 if (vfs_quota_enabled) { 3764 error = VOP_GETATTR(vp, &vattr); 3765 KASSERT(error == 0, ("kern_truncate(): VOP_GETATTR didn't return 0")); 3766 uid = vattr.va_uid; 3767 gid = vattr.va_gid; 3768 old_size = vattr.va_size; 3769 } 3770 3771 if ((error = vn_writechk(vp, &nd->nl_nch)) == 0) { 3772 VATTR_NULL(&vattr); 3773 vattr.va_size = length; 3774 error = VOP_SETATTR(vp, &vattr, nd->nl_cred); 3775 VFS_ACCOUNT(nd->nl_nch.mount, uid, gid, length - old_size); 3776 } 3777 done: 3778 vput(vp); 3779 return (error); 3780 } 3781 3782 /* 3783 * truncate(char *path, int pad, off_t length) 3784 * 3785 * Truncate a file given its path name. 3786 */ 3787 int 3788 sys_truncate(struct truncate_args *uap) 3789 { 3790 struct nlookupdata nd; 3791 int error; 3792 3793 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 3794 if (error == 0) 3795 error = kern_truncate(&nd, uap->length); 3796 nlookup_done(&nd); 3797 return error; 3798 } 3799 3800 int 3801 kern_ftruncate(int fd, off_t length) 3802 { 3803 struct thread *td = curthread; 3804 struct proc *p = td->td_proc; 3805 struct vattr vattr; 3806 struct vnode *vp; 3807 struct file *fp; 3808 int error; 3809 uid_t uid = 0; 3810 gid_t gid = 0; 3811 uint64_t old_size = 0; 3812 struct mount *mp; 3813 3814 if (length < 0) 3815 return(EINVAL); 3816 if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) 3817 return (error); 3818 if (fp->f_nchandle.ncp) { 3819 error = ncp_writechk(&fp->f_nchandle); 3820 if (error) 3821 goto done; 3822 } 3823 if ((fp->f_flag & FWRITE) == 0) { 3824 error = EINVAL; 3825 goto done; 3826 } 3827 if (fp->f_flag & FAPPENDONLY) { /* inode was set s/uapnd */ 3828 error = EINVAL; 3829 goto done; 3830 } 3831 vp = (struct vnode *)fp->f_data; 3832 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3833 if (vp->v_type == VDIR) { 3834 error = EISDIR; 3835 vn_unlock(vp); 3836 goto done; 3837 } 3838 3839 if (vfs_quota_enabled) { 3840 error = VOP_GETATTR(vp, &vattr); 3841 KASSERT(error == 0, ("kern_ftruncate(): VOP_GETATTR didn't return 0")); 3842 uid = vattr.va_uid; 3843 gid = vattr.va_gid; 3844 old_size = vattr.va_size; 3845 } 3846 3847 if ((error = vn_writechk(vp, NULL)) == 0) { 3848 VATTR_NULL(&vattr); 3849 vattr.va_size = length; 3850 error = VOP_SETATTR(vp, &vattr, fp->f_cred); 3851 mp = vq_vptomp(vp); 3852 VFS_ACCOUNT(mp, uid, gid, length - old_size); 3853 } 3854 vn_unlock(vp); 3855 done: 3856 fdrop(fp); 3857 return (error); 3858 } 3859 3860 /* 3861 * ftruncate_args(int fd, int pad, off_t length) 3862 * 3863 * Truncate a file given a file descriptor. 3864 */ 3865 int 3866 sys_ftruncate(struct ftruncate_args *uap) 3867 { 3868 int error; 3869 3870 error = kern_ftruncate(uap->fd, uap->length); 3871 3872 return (error); 3873 } 3874 3875 /* 3876 * fsync(int fd) 3877 * 3878 * Sync an open file. 3879 */ 3880 int 3881 sys_fsync(struct fsync_args *uap) 3882 { 3883 struct thread *td = curthread; 3884 struct proc *p = td->td_proc; 3885 struct vnode *vp; 3886 struct file *fp; 3887 vm_object_t obj; 3888 int error; 3889 3890 if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) 3891 return (error); 3892 vp = (struct vnode *)fp->f_data; 3893 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3894 if ((obj = vp->v_object) != NULL) { 3895 if (vp->v_mount == NULL || 3896 (vp->v_mount->mnt_kern_flag & MNTK_NOMSYNC) == 0) { 3897 vm_object_page_clean(obj, 0, 0, 0); 3898 } 3899 } 3900 error = VOP_FSYNC(vp, MNT_WAIT, VOP_FSYNC_SYSCALL); 3901 if (error == 0 && vp->v_mount) 3902 error = buf_fsync(vp); 3903 vn_unlock(vp); 3904 fdrop(fp); 3905 3906 return (error); 3907 } 3908 3909 int 3910 kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) 3911 { 3912 struct nchandle fnchd; 3913 struct nchandle tnchd; 3914 struct namecache *ncp; 3915 struct vnode *fdvp; 3916 struct vnode *tdvp; 3917 struct mount *mp; 3918 int error; 3919 u_int fncp_gen; 3920 u_int tncp_gen; 3921 3922 bwillinode(1); 3923 fromnd->nl_flags |= NLC_REFDVP | NLC_RENAME_SRC; 3924 if ((error = nlookup(fromnd)) != 0) 3925 return (error); 3926 if ((fnchd.ncp = fromnd->nl_nch.ncp->nc_parent) == NULL) 3927 return (ENOENT); 3928 fnchd.mount = fromnd->nl_nch.mount; 3929 cache_hold(&fnchd); 3930 3931 /* 3932 * unlock the source nch so we can lookup the target nch without 3933 * deadlocking. The target may or may not exist so we do not check 3934 * for a target vp like kern_mkdir() and other creation functions do. 3935 * 3936 * The source and target directories are ref'd and rechecked after 3937 * everything is relocked to determine if the source or target file 3938 * has been renamed. 3939 */ 3940 KKASSERT(fromnd->nl_flags & NLC_NCPISLOCKED); 3941 fromnd->nl_flags &= ~NLC_NCPISLOCKED; 3942 3943 fncp_gen = fromnd->nl_nch.ncp->nc_generation; 3944 3945 cache_unlock(&fromnd->nl_nch); 3946 3947 tond->nl_flags |= NLC_RENAME_DST | NLC_REFDVP; 3948 if ((error = nlookup(tond)) != 0) { 3949 cache_drop(&fnchd); 3950 return (error); 3951 } 3952 tncp_gen = tond->nl_nch.ncp->nc_generation; 3953 3954 if ((tnchd.ncp = tond->nl_nch.ncp->nc_parent) == NULL) { 3955 cache_drop(&fnchd); 3956 return (ENOENT); 3957 } 3958 tnchd.mount = tond->nl_nch.mount; 3959 cache_hold(&tnchd); 3960 3961 /* 3962 * If the source and target are the same there is nothing to do 3963 */ 3964 if (fromnd->nl_nch.ncp == tond->nl_nch.ncp) { 3965 cache_drop(&fnchd); 3966 cache_drop(&tnchd); 3967 return (0); 3968 } 3969 3970 /* 3971 * Mount points cannot be renamed or overwritten 3972 */ 3973 if ((fromnd->nl_nch.ncp->nc_flag | tond->nl_nch.ncp->nc_flag) & 3974 NCF_ISMOUNTPT 3975 ) { 3976 cache_drop(&fnchd); 3977 cache_drop(&tnchd); 3978 return (EINVAL); 3979 } 3980 3981 /* 3982 * Relock the source ncp. cache_relock() will deal with any 3983 * deadlocks against the already-locked tond and will also 3984 * make sure both are resolved. 3985 * 3986 * NOTE AFTER RELOCKING: The source or target ncp may have become 3987 * invalid while they were unlocked, nc_vp and nc_mount could 3988 * be NULL. 3989 */ 3990 cache_relock(&fromnd->nl_nch, fromnd->nl_cred, 3991 &tond->nl_nch, tond->nl_cred); 3992 fromnd->nl_flags |= NLC_NCPISLOCKED; 3993 3994 /* 3995 * If the namecache generation changed for either fromnd or tond, 3996 * we must retry. 3997 */ 3998 if (fromnd->nl_nch.ncp->nc_generation != fncp_gen || 3999 tond->nl_nch.ncp->nc_generation != tncp_gen) { 4000 kprintf("kern_rename: retry due to gen on: " 4001 "\"%s\" -> \"%s\"\n", 4002 fromnd->nl_nch.ncp->nc_name, 4003 tond->nl_nch.ncp->nc_name); 4004 cache_drop(&fnchd); 4005 cache_drop(&tnchd); 4006 return (EAGAIN); 4007 } 4008 4009 /* 4010 * If either fromnd or tond are marked destroyed a ripout occured 4011 * out from under us and we must retry. 4012 */ 4013 if ((fromnd->nl_nch.ncp->nc_flag & (NCF_DESTROYED | NCF_UNRESOLVED)) || 4014 fromnd->nl_nch.ncp->nc_vp == NULL || 4015 (tond->nl_nch.ncp->nc_flag & NCF_DESTROYED)) { 4016 kprintf("kern_rename: retry due to ripout on: " 4017 "\"%s\" -> \"%s\"\n", 4018 fromnd->nl_nch.ncp->nc_name, 4019 tond->nl_nch.ncp->nc_name); 4020 cache_drop(&fnchd); 4021 cache_drop(&tnchd); 4022 return (EAGAIN); 4023 } 4024 4025 /* 4026 * Make sure the parent directories linkages are the same. 4027 * XXX shouldn't be needed any more w/ generation check above. 4028 */ 4029 if (fnchd.ncp != fromnd->nl_nch.ncp->nc_parent || 4030 tnchd.ncp != tond->nl_nch.ncp->nc_parent) { 4031 cache_drop(&fnchd); 4032 cache_drop(&tnchd); 4033 return (ENOENT); 4034 } 4035 4036 /* 4037 * Both the source and target must be within the same filesystem and 4038 * in the same filesystem as their parent directories within the 4039 * namecache topology. 4040 * 4041 * NOTE: fromnd's nc_mount or nc_vp could be NULL. 4042 */ 4043 mp = fnchd.mount; 4044 if (mp != tnchd.mount || mp != fromnd->nl_nch.mount || 4045 mp != tond->nl_nch.mount) { 4046 cache_drop(&fnchd); 4047 cache_drop(&tnchd); 4048 return (EXDEV); 4049 } 4050 4051 /* 4052 * Make sure the mount point is writable 4053 */ 4054 if ((error = ncp_writechk(&tond->nl_nch)) != 0) { 4055 cache_drop(&fnchd); 4056 cache_drop(&tnchd); 4057 return (error); 4058 } 4059 4060 /* 4061 * If the target exists and either the source or target is a directory, 4062 * then both must be directories. 4063 * 4064 * Due to relocking of the source, fromnd->nl_nch.ncp->nc_vp might h 4065 * have become NULL. 4066 */ 4067 if (tond->nl_nch.ncp->nc_vp) { 4068 if (fromnd->nl_nch.ncp->nc_vp == NULL) { 4069 error = ENOENT; 4070 } else if (fromnd->nl_nch.ncp->nc_vp->v_type == VDIR) { 4071 if (tond->nl_nch.ncp->nc_vp->v_type != VDIR) 4072 error = ENOTDIR; 4073 } else if (tond->nl_nch.ncp->nc_vp->v_type == VDIR) { 4074 error = EISDIR; 4075 } 4076 } 4077 4078 /* 4079 * You cannot rename a source into itself or a subdirectory of itself. 4080 * We check this by travsersing the target directory upwards looking 4081 * for a match against the source. 4082 * 4083 * XXX MPSAFE 4084 */ 4085 if (error == 0) { 4086 for (ncp = tnchd.ncp; ncp; ncp = ncp->nc_parent) { 4087 if (fromnd->nl_nch.ncp == ncp) { 4088 error = EINVAL; 4089 break; 4090 } 4091 } 4092 } 4093 4094 cache_drop(&fnchd); 4095 cache_drop(&tnchd); 4096 4097 /* 4098 * Even though the namespaces are different, they may still represent 4099 * hardlinks to the same file. The filesystem might have a hard time 4100 * with this so we issue a NREMOVE of the source instead of a NRENAME 4101 * when we detect the situation. 4102 */ 4103 if (error == 0) { 4104 fdvp = fromnd->nl_dvp; 4105 tdvp = tond->nl_dvp; 4106 if (fdvp == NULL || tdvp == NULL) { 4107 error = EPERM; 4108 } else if (fromnd->nl_nch.ncp->nc_vp == tond->nl_nch.ncp->nc_vp) { 4109 error = VOP_NREMOVE(&fromnd->nl_nch, fdvp, 4110 fromnd->nl_cred); 4111 } else { 4112 error = VOP_NRENAME(&fromnd->nl_nch, &tond->nl_nch, 4113 fdvp, tdvp, tond->nl_cred); 4114 } 4115 } 4116 return (error); 4117 } 4118 4119 /* 4120 * rename_args(char *from, char *to) 4121 * 4122 * Rename files. Source and destination must either both be directories, 4123 * or both not be directories. If target is a directory, it must be empty. 4124 */ 4125 int 4126 sys_rename(struct rename_args *uap) 4127 { 4128 struct nlookupdata fromnd, tond; 4129 int error; 4130 4131 do { 4132 error = nlookup_init(&fromnd, uap->from, UIO_USERSPACE, 0); 4133 if (error == 0) { 4134 error = nlookup_init(&tond, uap->to, UIO_USERSPACE, 0); 4135 if (error == 0) 4136 error = kern_rename(&fromnd, &tond); 4137 nlookup_done(&tond); 4138 } 4139 nlookup_done(&fromnd); 4140 } while (error == EAGAIN); 4141 return (error); 4142 } 4143 4144 /* 4145 * renameat_args(int oldfd, char *old, int newfd, char *new) 4146 * 4147 * Rename files using paths relative to the directories associated with 4148 * oldfd and newfd. Source and destination must either both be directories, 4149 * or both not be directories. If target is a directory, it must be empty. 4150 */ 4151 int 4152 sys_renameat(struct renameat_args *uap) 4153 { 4154 struct nlookupdata oldnd, newnd; 4155 struct file *oldfp, *newfp; 4156 int error; 4157 4158 do { 4159 error = nlookup_init_at(&oldnd, &oldfp, 4160 uap->oldfd, uap->old, 4161 UIO_USERSPACE, 0); 4162 if (error == 0) { 4163 error = nlookup_init_at(&newnd, &newfp, 4164 uap->newfd, uap->new, 4165 UIO_USERSPACE, 0); 4166 if (error == 0) 4167 error = kern_rename(&oldnd, &newnd); 4168 nlookup_done_at(&newnd, newfp); 4169 } 4170 nlookup_done_at(&oldnd, oldfp); 4171 } while (error == EAGAIN); 4172 return (error); 4173 } 4174 4175 int 4176 kern_mkdir(struct nlookupdata *nd, int mode) 4177 { 4178 struct thread *td = curthread; 4179 struct proc *p = td->td_proc; 4180 struct vnode *vp; 4181 struct vattr vattr; 4182 int error; 4183 4184 bwillinode(1); 4185 nd->nl_flags |= NLC_WILLBEDIR | NLC_CREATE | NLC_REFDVP; 4186 if ((error = nlookup(nd)) != 0) 4187 return (error); 4188 4189 if (nd->nl_nch.ncp->nc_vp) 4190 return (EEXIST); 4191 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 4192 return (error); 4193 VATTR_NULL(&vattr); 4194 vattr.va_type = VDIR; 4195 vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask; 4196 4197 vp = NULL; 4198 error = VOP_NMKDIR(&nd->nl_nch, nd->nl_dvp, &vp, td->td_ucred, &vattr); 4199 if (error == 0) 4200 vput(vp); 4201 return (error); 4202 } 4203 4204 /* 4205 * mkdir_args(char *path, int mode) 4206 * 4207 * Make a directory file. 4208 */ 4209 int 4210 sys_mkdir(struct mkdir_args *uap) 4211 { 4212 struct nlookupdata nd; 4213 int error; 4214 4215 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 4216 if (error == 0) 4217 error = kern_mkdir(&nd, uap->mode); 4218 nlookup_done(&nd); 4219 return (error); 4220 } 4221 4222 /* 4223 * mkdirat_args(int fd, char *path, mode_t mode) 4224 * 4225 * Make a directory file. The path is relative to the directory associated 4226 * with fd. 4227 */ 4228 int 4229 sys_mkdirat(struct mkdirat_args *uap) 4230 { 4231 struct nlookupdata nd; 4232 struct file *fp; 4233 int error; 4234 4235 error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, UIO_USERSPACE, 0); 4236 if (error == 0) 4237 error = kern_mkdir(&nd, uap->mode); 4238 nlookup_done_at(&nd, fp); 4239 return (error); 4240 } 4241 4242 int 4243 kern_rmdir(struct nlookupdata *nd) 4244 { 4245 int error; 4246 4247 bwillinode(1); 4248 nd->nl_flags |= NLC_DELETE | NLC_REFDVP; 4249 if ((error = nlookup(nd)) != 0) 4250 return (error); 4251 4252 /* 4253 * Do not allow directories representing mount points to be 4254 * deleted, even if empty. Check write perms on mount point 4255 * in case the vnode is aliased (aka nullfs). 4256 */ 4257 if (nd->nl_nch.ncp->nc_flag & (NCF_ISMOUNTPT)) 4258 return (EBUSY); 4259 if ((error = ncp_writechk(&nd->nl_nch)) != 0) 4260 return (error); 4261 error = VOP_NRMDIR(&nd->nl_nch, nd->nl_dvp, nd->nl_cred); 4262 return (error); 4263 } 4264 4265 /* 4266 * rmdir_args(char *path) 4267 * 4268 * Remove a directory file. 4269 */ 4270 int 4271 sys_rmdir(struct rmdir_args *uap) 4272 { 4273 struct nlookupdata nd; 4274 int error; 4275 4276 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0); 4277 if (error == 0) 4278 error = kern_rmdir(&nd); 4279 nlookup_done(&nd); 4280 return (error); 4281 } 4282 4283 int 4284 kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res, 4285 enum uio_seg direction) 4286 { 4287 struct thread *td = curthread; 4288 struct proc *p = td->td_proc; 4289 struct vnode *vp; 4290 struct file *fp; 4291 struct uio auio; 4292 struct iovec aiov; 4293 off_t loff; 4294 int error, eofflag; 4295 4296 if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) 4297 return (error); 4298 if ((fp->f_flag & FREAD) == 0) { 4299 error = EBADF; 4300 goto done; 4301 } 4302 vp = (struct vnode *)fp->f_data; 4303 if (vp->v_type != VDIR) { 4304 error = EINVAL; 4305 goto done; 4306 } 4307 aiov.iov_base = buf; 4308 aiov.iov_len = count; 4309 auio.uio_iov = &aiov; 4310 auio.uio_iovcnt = 1; 4311 auio.uio_rw = UIO_READ; 4312 auio.uio_segflg = direction; 4313 auio.uio_td = td; 4314 auio.uio_resid = count; 4315 loff = auio.uio_offset = fp->f_offset; 4316 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 4317 fp->f_offset = auio.uio_offset; 4318 if (error) 4319 goto done; 4320 4321 /* 4322 * WARNING! *basep may not be wide enough to accomodate the 4323 * seek offset. XXX should we hack this to return the upper 32 bits 4324 * for offsets greater then 4G? 4325 */ 4326 if (basep) { 4327 *basep = (long)loff; 4328 } 4329 *res = count - auio.uio_resid; 4330 done: 4331 fdrop(fp); 4332 return (error); 4333 } 4334 4335 /* 4336 * getdirentries_args(int fd, char *buf, u_int conut, long *basep) 4337 * 4338 * Read a block of directory entries in a file system independent format. 4339 */ 4340 int 4341 sys_getdirentries(struct getdirentries_args *uap) 4342 { 4343 long base; 4344 int error; 4345 4346 error = kern_getdirentries(uap->fd, uap->buf, uap->count, &base, 4347 &uap->sysmsg_result, UIO_USERSPACE); 4348 4349 if (error == 0 && uap->basep) 4350 error = copyout(&base, uap->basep, sizeof(*uap->basep)); 4351 return (error); 4352 } 4353 4354 /* 4355 * getdents_args(int fd, char *buf, size_t count) 4356 */ 4357 int 4358 sys_getdents(struct getdents_args *uap) 4359 { 4360 int error; 4361 4362 error = kern_getdirentries(uap->fd, uap->buf, uap->count, NULL, 4363 &uap->sysmsg_result, UIO_USERSPACE); 4364 4365 return (error); 4366 } 4367 4368 /* 4369 * Set the mode mask for creation of filesystem nodes. 4370 * 4371 * umask(int newmask) 4372 */ 4373 int 4374 sys_umask(struct umask_args *uap) 4375 { 4376 struct thread *td = curthread; 4377 struct proc *p = td->td_proc; 4378 struct filedesc *fdp; 4379 4380 fdp = p->p_fd; 4381 uap->sysmsg_result = fdp->fd_cmask; 4382 fdp->fd_cmask = uap->newmask & ALLPERMS; 4383 return (0); 4384 } 4385 4386 /* 4387 * revoke(char *path) 4388 * 4389 * Void all references to file by ripping underlying filesystem 4390 * away from vnode. 4391 */ 4392 int 4393 sys_revoke(struct revoke_args *uap) 4394 { 4395 struct nlookupdata nd; 4396 struct vattr vattr; 4397 struct vnode *vp; 4398 struct ucred *cred; 4399 int error; 4400 4401 vp = NULL; 4402 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 4403 if (error == 0) 4404 error = nlookup(&nd); 4405 if (error == 0) 4406 error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); 4407 cred = crhold(nd.nl_cred); 4408 nlookup_done(&nd); 4409 if (error == 0) { 4410 if (error == 0) 4411 error = VOP_GETATTR(vp, &vattr); 4412 if (error == 0 && cred->cr_uid != vattr.va_uid) 4413 error = priv_check_cred(cred, PRIV_VFS_REVOKE, 0); 4414 if (error == 0 && (vp->v_type == VCHR || vp->v_type == VBLK)) { 4415 if (vcount(vp) > 0) 4416 error = vrevoke(vp, cred); 4417 } else if (error == 0) { 4418 error = vrevoke(vp, cred); 4419 } 4420 vrele(vp); 4421 } 4422 if (cred) 4423 crfree(cred); 4424 return (error); 4425 } 4426 4427 /* 4428 * getfh_args(char *fname, fhandle_t *fhp) 4429 * 4430 * Get (NFS) file handle 4431 * 4432 * NOTE: We use the fsid of the covering mount, even if it is a nullfs 4433 * mount. This allows nullfs mounts to be explicitly exported. 4434 * 4435 * WARNING: nullfs mounts of HAMMER PFS ROOTs are safe. 4436 * 4437 * nullfs mounts of subdirectories are not safe. That is, it will 4438 * work, but you do not really have protection against access to 4439 * the related parent directories. 4440 */ 4441 int 4442 sys_getfh(struct getfh_args *uap) 4443 { 4444 struct thread *td = curthread; 4445 struct nlookupdata nd; 4446 fhandle_t fh; 4447 struct vnode *vp; 4448 struct mount *mp; 4449 int error; 4450 4451 /* 4452 * Must be super user 4453 */ 4454 if ((error = priv_check(td, PRIV_ROOT)) != 0) 4455 return (error); 4456 4457 vp = NULL; 4458 error = nlookup_init(&nd, uap->fname, UIO_USERSPACE, NLC_FOLLOW); 4459 if (error == 0) 4460 error = nlookup(&nd); 4461 if (error == 0) 4462 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 4463 mp = nd.nl_nch.mount; 4464 nlookup_done(&nd); 4465 if (error == 0) { 4466 bzero(&fh, sizeof(fh)); 4467 fh.fh_fsid = mp->mnt_stat.f_fsid; 4468 error = VFS_VPTOFH(vp, &fh.fh_fid); 4469 vput(vp); 4470 if (error == 0) 4471 error = copyout(&fh, uap->fhp, sizeof(fh)); 4472 } 4473 return (error); 4474 } 4475 4476 /* 4477 * fhopen_args(const struct fhandle *u_fhp, int flags) 4478 * 4479 * syscall for the rpc.lockd to use to translate a NFS file handle into 4480 * an open descriptor. 4481 * 4482 * warning: do not remove the priv_check() call or this becomes one giant 4483 * security hole. 4484 */ 4485 int 4486 sys_fhopen(struct fhopen_args *uap) 4487 { 4488 struct thread *td = curthread; 4489 struct filedesc *fdp = td->td_proc->p_fd; 4490 struct mount *mp; 4491 struct vnode *vp; 4492 struct fhandle fhp; 4493 struct vattr vat; 4494 struct vattr *vap = &vat; 4495 struct flock lf; 4496 int fmode, mode, error = 0, type; 4497 struct file *nfp; 4498 struct file *fp; 4499 int indx; 4500 4501 /* 4502 * Must be super user 4503 */ 4504 error = priv_check(td, PRIV_ROOT); 4505 if (error) 4506 return (error); 4507 4508 fmode = FFLAGS(uap->flags); 4509 4510 /* 4511 * Why not allow a non-read/write open for our lockd? 4512 */ 4513 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 4514 return (EINVAL); 4515 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 4516 if (error) 4517 return(error); 4518 4519 /* 4520 * Find the mount point 4521 */ 4522 mp = vfs_getvfs(&fhp.fh_fsid); 4523 if (mp == NULL) { 4524 error = ESTALE; 4525 goto done; 4526 } 4527 /* now give me my vnode, it gets returned to me locked */ 4528 error = VFS_FHTOVP(mp, NULL, &fhp.fh_fid, &vp); 4529 if (error) 4530 goto done; 4531 /* 4532 * from now on we have to make sure not 4533 * to forget about the vnode 4534 * any error that causes an abort must vput(vp) 4535 * just set error = err and 'goto bad;'. 4536 */ 4537 4538 /* 4539 * from vn_open 4540 */ 4541 if (vp->v_type == VLNK) { 4542 error = EMLINK; 4543 goto bad; 4544 } 4545 if (vp->v_type == VSOCK) { 4546 error = EOPNOTSUPP; 4547 goto bad; 4548 } 4549 mode = 0; 4550 if (fmode & (FWRITE | O_TRUNC)) { 4551 if (vp->v_type == VDIR) { 4552 error = EISDIR; 4553 goto bad; 4554 } 4555 error = vn_writechk(vp, NULL); 4556 if (error) 4557 goto bad; 4558 mode |= VWRITE; 4559 } 4560 if (fmode & FREAD) 4561 mode |= VREAD; 4562 if (mode) { 4563 error = VOP_ACCESS(vp, mode, td->td_ucred); 4564 if (error) 4565 goto bad; 4566 } 4567 if (fmode & O_TRUNC) { 4568 vn_unlock(vp); /* XXX */ 4569 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ 4570 VATTR_NULL(vap); 4571 vap->va_size = 0; 4572 error = VOP_SETATTR(vp, vap, td->td_ucred); 4573 if (error) 4574 goto bad; 4575 } 4576 4577 /* 4578 * VOP_OPEN needs the file pointer so it can potentially override 4579 * it. 4580 * 4581 * WARNING! no f_nchandle will be associated when fhopen()ing a 4582 * directory. XXX 4583 */ 4584 if ((error = falloc(td->td_lwp, &nfp, &indx)) != 0) 4585 goto bad; 4586 fp = nfp; 4587 4588 error = VOP_OPEN(vp, fmode, td->td_ucred, fp); 4589 if (error) { 4590 /* 4591 * setting f_ops this way prevents VOP_CLOSE from being 4592 * called or fdrop() releasing the vp from v_data. Since 4593 * the VOP_OPEN failed we don't want to VOP_CLOSE. 4594 */ 4595 fp->f_ops = &badfileops; 4596 fp->f_data = NULL; 4597 goto bad_drop; 4598 } 4599 4600 /* 4601 * The fp is given its own reference, we still have our ref and lock. 4602 * 4603 * Assert that all regular files must be created with a VM object. 4604 */ 4605 if (vp->v_type == VREG && vp->v_object == NULL) { 4606 kprintf("fhopen: regular file did not have VM object: %p\n", vp); 4607 goto bad_drop; 4608 } 4609 4610 /* 4611 * The open was successful. Handle any locking requirements. 4612 */ 4613 if (fmode & (O_EXLOCK | O_SHLOCK)) { 4614 lf.l_whence = SEEK_SET; 4615 lf.l_start = 0; 4616 lf.l_len = 0; 4617 if (fmode & O_EXLOCK) 4618 lf.l_type = F_WRLCK; 4619 else 4620 lf.l_type = F_RDLCK; 4621 if (fmode & FNONBLOCK) 4622 type = 0; 4623 else 4624 type = F_WAIT; 4625 vn_unlock(vp); 4626 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 4627 /* 4628 * release our private reference. 4629 */ 4630 fsetfd(fdp, NULL, indx); 4631 fdrop(fp); 4632 vrele(vp); 4633 goto done; 4634 } 4635 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4636 atomic_set_int(&fp->f_flag, FHASLOCK); /* race ok */ 4637 } 4638 4639 /* 4640 * Clean up. Associate the file pointer with the previously 4641 * reserved descriptor and return it. 4642 */ 4643 vput(vp); 4644 if (uap->flags & O_CLOEXEC) 4645 fdp->fd_files[indx].fileflags |= UF_EXCLOSE; 4646 fsetfd(fdp, fp, indx); 4647 fdrop(fp); 4648 uap->sysmsg_result = indx; 4649 return (error); 4650 4651 bad_drop: 4652 fsetfd(fdp, NULL, indx); 4653 fdrop(fp); 4654 bad: 4655 vput(vp); 4656 done: 4657 return (error); 4658 } 4659 4660 /* 4661 * fhstat_args(struct fhandle *u_fhp, struct stat *sb) 4662 */ 4663 int 4664 sys_fhstat(struct fhstat_args *uap) 4665 { 4666 struct thread *td = curthread; 4667 struct stat sb; 4668 fhandle_t fh; 4669 struct mount *mp; 4670 struct vnode *vp; 4671 int error; 4672 4673 /* 4674 * Must be super user 4675 */ 4676 error = priv_check(td, PRIV_ROOT); 4677 if (error) 4678 return (error); 4679 4680 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4681 if (error) 4682 return (error); 4683 4684 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 4685 error = ESTALE; 4686 if (error == 0) { 4687 if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp)) == 0) { 4688 error = vn_stat(vp, &sb, td->td_ucred); 4689 vput(vp); 4690 } 4691 } 4692 if (error == 0) 4693 error = copyout(&sb, uap->sb, sizeof(sb)); 4694 return (error); 4695 } 4696 4697 /* 4698 * fhstatfs_args(struct fhandle *u_fhp, struct statfs *buf) 4699 */ 4700 int 4701 sys_fhstatfs(struct fhstatfs_args *uap) 4702 { 4703 struct thread *td = curthread; 4704 struct proc *p = td->td_proc; 4705 struct statfs *sp; 4706 struct mount *mp; 4707 struct vnode *vp; 4708 struct statfs sb; 4709 char *fullpath, *freepath; 4710 fhandle_t fh; 4711 int error; 4712 4713 /* 4714 * Must be super user 4715 */ 4716 if ((error = priv_check(td, PRIV_ROOT))) 4717 return (error); 4718 4719 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 4720 return (error); 4721 4722 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) { 4723 error = ESTALE; 4724 goto done; 4725 } 4726 if (p != NULL && !chroot_visible_mnt(mp, p)) { 4727 error = ESTALE; 4728 goto done; 4729 } 4730 4731 if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp)) != 0) 4732 goto done; 4733 mp = vp->v_mount; 4734 sp = &mp->mnt_stat; 4735 vput(vp); 4736 if ((error = VFS_STATFS(mp, sp, td->td_ucred)) != 0) 4737 goto done; 4738 4739 error = mount_path(p, mp, &fullpath, &freepath); 4740 if (error) 4741 goto done; 4742 bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); 4743 strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); 4744 kfree(freepath, M_TEMP); 4745 4746 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 4747 if (priv_check(td, PRIV_ROOT)) { 4748 bcopy(sp, &sb, sizeof(sb)); 4749 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 4750 sp = &sb; 4751 } 4752 error = copyout(sp, uap->buf, sizeof(*sp)); 4753 done: 4754 return (error); 4755 } 4756 4757 /* 4758 * fhstatvfs_args(struct fhandle *u_fhp, struct statvfs *buf) 4759 */ 4760 int 4761 sys_fhstatvfs(struct fhstatvfs_args *uap) 4762 { 4763 struct thread *td = curthread; 4764 struct proc *p = td->td_proc; 4765 struct statvfs *sp; 4766 struct mount *mp; 4767 struct vnode *vp; 4768 fhandle_t fh; 4769 int error; 4770 4771 /* 4772 * Must be super user 4773 */ 4774 if ((error = priv_check(td, PRIV_ROOT))) 4775 return (error); 4776 4777 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 4778 return (error); 4779 4780 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) { 4781 error = ESTALE; 4782 goto done; 4783 } 4784 if (p != NULL && !chroot_visible_mnt(mp, p)) { 4785 error = ESTALE; 4786 goto done; 4787 } 4788 4789 if ((error = VFS_FHTOVP(mp, NULL, &fh.fh_fid, &vp))) 4790 goto done; 4791 mp = vp->v_mount; 4792 sp = &mp->mnt_vstat; 4793 vput(vp); 4794 if ((error = VFS_STATVFS(mp, sp, td->td_ucred)) != 0) 4795 goto done; 4796 4797 sp->f_flag = 0; 4798 if (mp->mnt_flag & MNT_RDONLY) 4799 sp->f_flag |= ST_RDONLY; 4800 if (mp->mnt_flag & MNT_NOSUID) 4801 sp->f_flag |= ST_NOSUID; 4802 error = copyout(sp, uap->buf, sizeof(*sp)); 4803 done: 4804 return (error); 4805 } 4806 4807 4808 /* 4809 * Syscall to push extended attribute configuration information into the 4810 * VFS. Accepts a path, which it converts to a mountpoint, as well as 4811 * a command (int cmd), and attribute name and misc data. For now, the 4812 * attribute name is left in userspace for consumption by the VFS_op. 4813 * It will probably be changed to be copied into sysspace by the 4814 * syscall in the future, once issues with various consumers of the 4815 * attribute code have raised their hands. 4816 * 4817 * Currently this is used only by UFS Extended Attributes. 4818 */ 4819 int 4820 sys_extattrctl(struct extattrctl_args *uap) 4821 { 4822 struct nlookupdata nd; 4823 struct vnode *vp; 4824 char attrname[EXTATTR_MAXNAMELEN]; 4825 int error; 4826 size_t size; 4827 4828 attrname[0] = 0; 4829 vp = NULL; 4830 error = 0; 4831 4832 if (error == 0 && uap->filename) { 4833 error = nlookup_init(&nd, uap->filename, UIO_USERSPACE, 4834 NLC_FOLLOW); 4835 if (error == 0) 4836 error = nlookup(&nd); 4837 if (error == 0) 4838 error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); 4839 nlookup_done(&nd); 4840 } 4841 4842 if (error == 0 && uap->attrname) { 4843 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, 4844 &size); 4845 } 4846 4847 if (error == 0) { 4848 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 4849 if (error == 0) 4850 error = nlookup(&nd); 4851 if (error == 0) 4852 error = ncp_writechk(&nd.nl_nch); 4853 if (error == 0) { 4854 error = VFS_EXTATTRCTL(nd.nl_nch.mount, uap->cmd, vp, 4855 uap->attrnamespace, 4856 uap->attrname, nd.nl_cred); 4857 } 4858 nlookup_done(&nd); 4859 } 4860 4861 return (error); 4862 } 4863 4864 /* 4865 * Syscall to get a named extended attribute on a file or directory. 4866 */ 4867 int 4868 sys_extattr_set_file(struct extattr_set_file_args *uap) 4869 { 4870 char attrname[EXTATTR_MAXNAMELEN]; 4871 struct nlookupdata nd; 4872 struct vnode *vp; 4873 struct uio auio; 4874 struct iovec aiov; 4875 int error; 4876 4877 error = copyin(uap->attrname, attrname, EXTATTR_MAXNAMELEN); 4878 if (error) 4879 return (error); 4880 4881 vp = NULL; 4882 4883 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 4884 if (error == 0) 4885 error = nlookup(&nd); 4886 if (error == 0) 4887 error = ncp_writechk(&nd.nl_nch); 4888 if (error == 0) 4889 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 4890 if (error) { 4891 nlookup_done(&nd); 4892 return (error); 4893 } 4894 4895 bzero(&auio, sizeof(auio)); 4896 aiov.iov_base = uap->data; 4897 aiov.iov_len = uap->nbytes; 4898 auio.uio_iov = &aiov; 4899 auio.uio_iovcnt = 1; 4900 auio.uio_offset = 0; 4901 auio.uio_resid = uap->nbytes; 4902 auio.uio_rw = UIO_WRITE; 4903 auio.uio_td = curthread; 4904 4905 error = VOP_SETEXTATTR(vp, uap->attrnamespace, attrname, 4906 &auio, nd.nl_cred); 4907 4908 vput(vp); 4909 nlookup_done(&nd); 4910 return (error); 4911 } 4912 4913 /* 4914 * Syscall to get a named extended attribute on a file or directory. 4915 */ 4916 int 4917 sys_extattr_get_file(struct extattr_get_file_args *uap) 4918 { 4919 char attrname[EXTATTR_MAXNAMELEN]; 4920 struct nlookupdata nd; 4921 struct uio auio; 4922 struct iovec aiov; 4923 struct vnode *vp; 4924 int error; 4925 4926 error = copyin(uap->attrname, attrname, EXTATTR_MAXNAMELEN); 4927 if (error) 4928 return (error); 4929 4930 vp = NULL; 4931 4932 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 4933 if (error == 0) 4934 error = nlookup(&nd); 4935 if (error == 0) 4936 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_SHARED, &vp); 4937 if (error) { 4938 nlookup_done(&nd); 4939 return (error); 4940 } 4941 4942 bzero(&auio, sizeof(auio)); 4943 aiov.iov_base = uap->data; 4944 aiov.iov_len = uap->nbytes; 4945 auio.uio_iov = &aiov; 4946 auio.uio_iovcnt = 1; 4947 auio.uio_offset = 0; 4948 auio.uio_resid = uap->nbytes; 4949 auio.uio_rw = UIO_READ; 4950 auio.uio_td = curthread; 4951 4952 error = VOP_GETEXTATTR(vp, uap->attrnamespace, attrname, 4953 &auio, nd.nl_cred); 4954 uap->sysmsg_result = uap->nbytes - auio.uio_resid; 4955 4956 vput(vp); 4957 nlookup_done(&nd); 4958 return(error); 4959 } 4960 4961 /* 4962 * Syscall to delete a named extended attribute from a file or directory. 4963 * Accepts attribute name. The real work happens in VOP_SETEXTATTR(). 4964 */ 4965 int 4966 sys_extattr_delete_file(struct extattr_delete_file_args *uap) 4967 { 4968 char attrname[EXTATTR_MAXNAMELEN]; 4969 struct nlookupdata nd; 4970 struct vnode *vp; 4971 int error; 4972 4973 error = copyin(uap->attrname, attrname, EXTATTR_MAXNAMELEN); 4974 if (error) 4975 return(error); 4976 4977 error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); 4978 if (error == 0) 4979 error = nlookup(&nd); 4980 if (error == 0) 4981 error = ncp_writechk(&nd.nl_nch); 4982 if (error == 0) { 4983 error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); 4984 if (error == 0) { 4985 error = VOP_SETEXTATTR(vp, uap->attrnamespace, 4986 attrname, NULL, nd.nl_cred); 4987 vput(vp); 4988 } 4989 } 4990 nlookup_done(&nd); 4991 return(error); 4992 } 4993 4994 /* 4995 * Determine if the mount is visible to the process. 4996 */ 4997 static int 4998 chroot_visible_mnt(struct mount *mp, struct proc *p) 4999 { 5000 struct nchandle nch; 5001 5002 /* 5003 * Traverse from the mount point upwards. If we hit the process 5004 * root then the mount point is visible to the process. 5005 */ 5006 nch = mp->mnt_ncmountpt; 5007 while (nch.ncp) { 5008 if (nch.mount == p->p_fd->fd_nrdir.mount && 5009 nch.ncp == p->p_fd->fd_nrdir.ncp) { 5010 return(1); 5011 } 5012 if (nch.ncp == nch.mount->mnt_ncmountpt.ncp) { 5013 nch = nch.mount->mnt_ncmounton; 5014 } else { 5015 nch.ncp = nch.ncp->nc_parent; 5016 } 5017 } 5018 5019 /* 5020 * If the mount point is not visible to the process, but the 5021 * process root is in a subdirectory of the mount, return 5022 * TRUE anyway. 5023 */ 5024 if (p->p_fd->fd_nrdir.mount == mp) 5025 return(1); 5026 5027 return(0); 5028 } 5029 5030