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