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