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