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