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.19 2003/09/29 18:52:06 dillon Exp $ 41 */ 42 43 /* For 4.3 integer FS ID compatibility */ 44 #include "opt_compat.h" 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/buf.h> 49 #include <sys/sysent.h> 50 #include <sys/malloc.h> 51 #include <sys/mount.h> 52 #include <sys/sysproto.h> 53 #include <sys/filedesc.h> 54 #include <sys/kernel.h> 55 #include <sys/fcntl.h> 56 #include <sys/file.h> 57 #include <sys/linker.h> 58 #include <sys/stat.h> 59 #include <sys/unistd.h> 60 #include <sys/vnode.h> 61 #include <sys/proc.h> 62 #include <sys/namei.h> 63 #include <sys/dirent.h> 64 #include <sys/extattr.h> 65 66 #include <machine/limits.h> 67 #include <vfs/union/union.h> 68 #include <sys/sysctl.h> 69 #include <vm/vm.h> 70 #include <vm/vm_object.h> 71 #include <vm/vm_zone.h> 72 #include <vm/vm_page.h> 73 74 #include <sys/file2.h> 75 76 static int change_dir (struct nameidata *ndp, struct thread *td); 77 static void checkdirs (struct vnode *olddp); 78 static int chroot_refuse_vdir_fds (struct filedesc *fdp); 79 static int getutimes (const struct timeval *, struct timespec *); 80 static int setfown (struct vnode *, uid_t, gid_t); 81 static int setfmode (struct vnode *, int); 82 static int setfflags (struct vnode *, int); 83 static int setutimes (struct vnode *, const struct timespec *, int); 84 static int usermount = 0; /* if 1, non-root can mount fs. */ 85 86 int (*union_dircheckp) (struct thread *, struct vnode **, struct file *); 87 88 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); 89 90 /* 91 * Virtual File System System Calls 92 */ 93 94 /* 95 * Mount a file system. 96 */ 97 /* 98 * mount_args(char *type, char *path, int flags, caddr_t data) 99 */ 100 /* ARGSUSED */ 101 int 102 mount(struct mount_args *uap) 103 { 104 struct thread *td = curthread; 105 struct proc *p = td->td_proc; 106 struct vnode *vp; 107 struct mount *mp; 108 struct vfsconf *vfsp; 109 int error, flag = 0, flag2 = 0; 110 struct vattr va; 111 #ifdef COMPAT_43 112 u_long fstypenum; 113 #endif 114 struct nameidata nd; 115 char fstypename[MFSNAMELEN]; 116 117 if (usermount == 0 && (error = suser(td))) 118 return (error); 119 /* 120 * Do not allow NFS export by non-root users. 121 */ 122 if (SCARG(uap, flags) & MNT_EXPORTED) { 123 error = suser(td); 124 if (error) 125 return (error); 126 } 127 /* 128 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users 129 */ 130 if (suser(td)) 131 SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV; 132 /* 133 * Get vnode to be covered 134 */ 135 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 136 SCARG(uap, path), td); 137 if ((error = namei(&nd)) != 0) 138 return (error); 139 NDFREE(&nd, NDF_ONLY_PNBUF); 140 vp = nd.ni_vp; 141 if (SCARG(uap, flags) & MNT_UPDATE) { 142 if ((vp->v_flag & VROOT) == 0) { 143 vput(vp); 144 return (EINVAL); 145 } 146 mp = vp->v_mount; 147 flag = mp->mnt_flag; 148 flag2 = mp->mnt_kern_flag; 149 /* 150 * We only allow the filesystem to be reloaded if it 151 * is currently mounted read-only. 152 */ 153 if ((SCARG(uap, flags) & MNT_RELOAD) && 154 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 155 vput(vp); 156 return (EOPNOTSUPP); /* Needs translation */ 157 } 158 /* 159 * Only root, or the user that did the original mount is 160 * permitted to update it. 161 */ 162 if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid && 163 (error = suser(td))) { 164 vput(vp); 165 return (error); 166 } 167 if (vfs_busy(mp, LK_NOWAIT, 0, td)) { 168 vput(vp); 169 return (EBUSY); 170 } 171 lwkt_gettoken(&vp->v_interlock); 172 if ((vp->v_flag & VMOUNT) != 0 || 173 vp->v_mountedhere != NULL) { 174 lwkt_reltoken(&vp->v_interlock); 175 vfs_unbusy(mp, td); 176 vput(vp); 177 return (EBUSY); 178 } 179 vp->v_flag |= VMOUNT; 180 lwkt_reltoken(&vp->v_interlock); 181 mp->mnt_flag |= 182 SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE); 183 VOP_UNLOCK(vp, 0, td); 184 goto update; 185 } 186 /* 187 * If the user is not root, ensure that they own the directory 188 * onto which we are attempting to mount. 189 */ 190 if ((error = VOP_GETATTR(vp, &va, td)) || 191 (va.va_uid != p->p_ucred->cr_uid && 192 (error = suser(td)))) { 193 vput(vp); 194 return (error); 195 } 196 if ((error = vinvalbuf(vp, V_SAVE, td, 0, 0)) != 0) { 197 vput(vp); 198 return (error); 199 } 200 if (vp->v_type != VDIR) { 201 vput(vp); 202 return (ENOTDIR); 203 } 204 #ifdef COMPAT_43 205 /* 206 * Historically filesystem types were identified by number. If we 207 * get an integer for the filesystem type instead of a string, we 208 * check to see if it matches one of the historic filesystem types. 209 */ 210 fstypenum = (uintptr_t)SCARG(uap, type); 211 if (fstypenum < maxvfsconf) { 212 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 213 if (vfsp->vfc_typenum == fstypenum) 214 break; 215 if (vfsp == NULL) { 216 vput(vp); 217 return (ENODEV); 218 } 219 strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN); 220 } else 221 #endif /* COMPAT_43 */ 222 if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) { 223 vput(vp); 224 return (error); 225 } 226 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 227 if (!strcmp(vfsp->vfc_name, fstypename)) 228 break; 229 if (vfsp == NULL) { 230 linker_file_t lf; 231 232 /* Only load modules for root (very important!) */ 233 if ((error = suser(td)) != 0) { 234 vput(vp); 235 return error; 236 } 237 error = linker_load_file(fstypename, &lf); 238 if (error || lf == NULL) { 239 vput(vp); 240 if (lf == NULL) 241 error = ENODEV; 242 return error; 243 } 244 lf->userrefs++; 245 /* lookup again, see if the VFS was loaded */ 246 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 247 if (!strcmp(vfsp->vfc_name, fstypename)) 248 break; 249 if (vfsp == NULL) { 250 lf->userrefs--; 251 linker_file_unload(lf); 252 vput(vp); 253 return (ENODEV); 254 } 255 } 256 lwkt_gettoken(&vp->v_interlock); 257 if ((vp->v_flag & VMOUNT) != 0 || 258 vp->v_mountedhere != NULL) { 259 lwkt_reltoken(&vp->v_interlock); 260 vput(vp); 261 return (EBUSY); 262 } 263 vp->v_flag |= VMOUNT; 264 lwkt_reltoken(&vp->v_interlock); 265 266 /* 267 * Allocate and initialize the filesystem. 268 */ 269 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK); 270 bzero((char *)mp, (u_long)sizeof(struct mount)); 271 TAILQ_INIT(&mp->mnt_nvnodelist); 272 TAILQ_INIT(&mp->mnt_reservedvnlist); 273 mp->mnt_nvnodelistsize = 0; 274 lockinit(&mp->mnt_lock, 0, "vfslock", 0, LK_NOPAUSE); 275 (void)vfs_busy(mp, LK_NOWAIT, 0, td); 276 mp->mnt_op = vfsp->vfc_vfsops; 277 mp->mnt_vfc = vfsp; 278 vfsp->vfc_refcount++; 279 mp->mnt_stat.f_type = vfsp->vfc_typenum; 280 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 281 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 282 mp->mnt_vnodecovered = vp; 283 mp->mnt_stat.f_owner = p->p_ucred->cr_uid; 284 mp->mnt_iosize_max = DFLTPHYS; 285 VOP_UNLOCK(vp, 0, td); 286 update: 287 /* 288 * Set the mount level flags. 289 */ 290 if (SCARG(uap, flags) & MNT_RDONLY) 291 mp->mnt_flag |= MNT_RDONLY; 292 else if (mp->mnt_flag & MNT_RDONLY) 293 mp->mnt_kern_flag |= MNTK_WANTRDWR; 294 mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | 295 MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | 296 MNT_NOSYMFOLLOW | MNT_IGNORE | 297 MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 298 mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | 299 MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | 300 MNT_NOSYMFOLLOW | MNT_IGNORE | 301 MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 302 /* 303 * Mount the filesystem. 304 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 305 * get. No freeing of cn_pnbuf. 306 */ 307 error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, td); 308 if (mp->mnt_flag & MNT_UPDATE) { 309 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 310 mp->mnt_flag &= ~MNT_RDONLY; 311 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE); 312 mp->mnt_kern_flag &=~ MNTK_WANTRDWR; 313 if (error) { 314 mp->mnt_flag = flag; 315 mp->mnt_kern_flag = flag2; 316 } 317 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 318 if (mp->mnt_syncer == NULL) 319 error = vfs_allocate_syncvnode(mp); 320 } else { 321 if (mp->mnt_syncer != NULL) 322 vrele(mp->mnt_syncer); 323 mp->mnt_syncer = NULL; 324 } 325 vfs_unbusy(mp, td); 326 lwkt_gettoken(&vp->v_interlock); 327 vp->v_flag &= ~VMOUNT; 328 lwkt_reltoken(&vp->v_interlock); 329 vrele(vp); 330 return (error); 331 } 332 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 333 /* 334 * Put the new filesystem on the mount list after root. 335 */ 336 cache_purge(vp); 337 if (!error) { 338 lwkt_gettoken(&vp->v_interlock); 339 vp->v_flag &= ~VMOUNT; 340 vp->v_mountedhere = mp; 341 lwkt_reltoken(&vp->v_interlock); 342 lwkt_gettoken(&mountlist_token); 343 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 344 lwkt_reltoken(&mountlist_token); 345 checkdirs(vp); 346 VOP_UNLOCK(vp, 0, td); 347 if ((mp->mnt_flag & MNT_RDONLY) == 0) 348 error = vfs_allocate_syncvnode(mp); 349 vfs_unbusy(mp, td); 350 if ((error = VFS_START(mp, 0, td)) != 0) 351 vrele(vp); 352 } else { 353 lwkt_gettoken(&vp->v_interlock); 354 vp->v_flag &= ~VMOUNT; 355 lwkt_reltoken(&vp->v_interlock); 356 mp->mnt_vfc->vfc_refcount--; 357 vfs_unbusy(mp, td); 358 free((caddr_t)mp, M_MOUNT); 359 vput(vp); 360 } 361 return (error); 362 } 363 364 /* 365 * Scan all active processes to see if any of them have a current 366 * or root directory onto which the new filesystem has just been 367 * mounted. If so, replace them with the new mount point. 368 */ 369 static void 370 checkdirs(struct vnode *olddp) 371 { 372 struct filedesc *fdp; 373 struct vnode *newdp; 374 struct proc *p; 375 376 if (olddp->v_usecount == 1) 377 return; 378 if (VFS_ROOT(olddp->v_mountedhere, &newdp)) 379 panic("mount: lost mount"); 380 FOREACH_PROC_IN_SYSTEM(p) { 381 fdp = p->p_fd; 382 if (fdp->fd_cdir == olddp) { 383 vrele(fdp->fd_cdir); 384 VREF(newdp); 385 fdp->fd_cdir = newdp; 386 } 387 if (fdp->fd_rdir == olddp) { 388 vrele(fdp->fd_rdir); 389 VREF(newdp); 390 fdp->fd_rdir = newdp; 391 } 392 } 393 if (rootvnode == olddp) { 394 vrele(rootvnode); 395 VREF(newdp); 396 rootvnode = newdp; 397 vfs_cache_setroot(rootvnode); 398 } 399 vput(newdp); 400 } 401 402 /* 403 * Unmount a file system. 404 * 405 * Note: unmount takes a path to the vnode mounted on as argument, 406 * not special file (as before). 407 */ 408 /* 409 * umount_args(char *path, int flags) 410 */ 411 /* ARGSUSED */ 412 int 413 unmount(struct unmount_args *uap) 414 { 415 struct thread *td = curthread; 416 struct proc *p = td->td_proc; 417 struct vnode *vp; 418 struct mount *mp; 419 int error; 420 struct nameidata nd; 421 422 KKASSERT(p); 423 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 424 SCARG(uap, path), td); 425 if ((error = namei(&nd)) != 0) 426 return (error); 427 vp = nd.ni_vp; 428 NDFREE(&nd, NDF_ONLY_PNBUF); 429 mp = vp->v_mount; 430 431 /* 432 * Only root, or the user that did the original mount is 433 * permitted to unmount this filesystem. 434 */ 435 if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) && 436 (error = suser(td))) { 437 vput(vp); 438 return (error); 439 } 440 441 /* 442 * Don't allow unmounting the root file system. 443 */ 444 if (mp->mnt_flag & MNT_ROOTFS) { 445 vput(vp); 446 return (EINVAL); 447 } 448 449 /* 450 * Must be the root of the filesystem 451 */ 452 if ((vp->v_flag & VROOT) == 0) { 453 vput(vp); 454 return (EINVAL); 455 } 456 vput(vp); 457 return (dounmount(mp, SCARG(uap, flags), td)); 458 } 459 460 /* 461 * Do the actual file system unmount. 462 */ 463 int 464 dounmount(struct mount *mp, int flags, struct thread *td) 465 { 466 struct vnode *coveredvp; 467 int error; 468 int async_flag; 469 470 lwkt_gettoken(&mountlist_token); 471 if (mp->mnt_kern_flag & MNTK_UNMOUNT) { 472 lwkt_reltoken(&mountlist_token); 473 return (EBUSY); 474 } 475 mp->mnt_kern_flag |= MNTK_UNMOUNT; 476 /* Allow filesystems to detect that a forced unmount is in progress. */ 477 if (flags & MNT_FORCE) 478 mp->mnt_kern_flag |= MNTK_UNMOUNTF; 479 error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK | 480 ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_token, td); 481 if (error) { 482 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 483 if (mp->mnt_kern_flag & MNTK_MWAIT) 484 wakeup((caddr_t)mp); 485 return (error); 486 } 487 488 if (mp->mnt_flag & MNT_EXPUBLIC) 489 vfs_setpublicfs(NULL, NULL, NULL); 490 491 vfs_msync(mp, MNT_WAIT); 492 async_flag = mp->mnt_flag & MNT_ASYNC; 493 mp->mnt_flag &=~ MNT_ASYNC; 494 cache_purgevfs(mp); /* remove cache entries for this file sys */ 495 if (mp->mnt_syncer != NULL) 496 vrele(mp->mnt_syncer); 497 if (((mp->mnt_flag & MNT_RDONLY) || 498 (error = VFS_SYNC(mp, MNT_WAIT, td)) == 0) || 499 (flags & MNT_FORCE)) 500 error = VFS_UNMOUNT(mp, flags, td); 501 lwkt_gettoken(&mountlist_token); 502 if (error) { 503 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 504 (void) vfs_allocate_syncvnode(mp); 505 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 506 mp->mnt_flag |= async_flag; 507 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, 508 &mountlist_token, td); 509 if (mp->mnt_kern_flag & MNTK_MWAIT) 510 wakeup((caddr_t)mp); 511 return (error); 512 } 513 TAILQ_REMOVE(&mountlist, mp, mnt_list); 514 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { 515 coveredvp->v_mountedhere = NULL; 516 vrele(coveredvp); 517 } 518 mp->mnt_vfc->vfc_refcount--; 519 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) 520 panic("unmount: dangling vnode"); 521 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_token, td); 522 if (mp->mnt_kern_flag & MNTK_MWAIT) 523 wakeup((caddr_t)mp); 524 free((caddr_t)mp, M_MOUNT); 525 return (0); 526 } 527 528 /* 529 * Sync each mounted filesystem. 530 */ 531 532 #ifdef DEBUG 533 static int syncprt = 0; 534 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 535 #endif 536 537 /* ARGSUSED */ 538 int 539 sync(struct sync_args *uap) 540 { 541 struct thread *td = curthread; 542 struct mount *mp, *nmp; 543 int asyncflag; 544 545 lwkt_gettoken(&mountlist_token); 546 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { 547 if (vfs_busy(mp, LK_NOWAIT, &mountlist_token, td)) { 548 nmp = TAILQ_NEXT(mp, mnt_list); 549 continue; 550 } 551 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 552 asyncflag = mp->mnt_flag & MNT_ASYNC; 553 mp->mnt_flag &= ~MNT_ASYNC; 554 vfs_msync(mp, MNT_NOWAIT); 555 VFS_SYNC(mp, MNT_NOWAIT, td); 556 mp->mnt_flag |= asyncflag; 557 } 558 lwkt_gettoken(&mountlist_token); 559 nmp = TAILQ_NEXT(mp, mnt_list); 560 vfs_unbusy(mp, td); 561 } 562 lwkt_reltoken(&mountlist_token); 563 #if 0 564 /* 565 * XXX don't call vfs_bufstats() yet because that routine 566 * was not imported in the Lite2 merge. 567 */ 568 #ifdef DIAGNOSTIC 569 if (syncprt) 570 vfs_bufstats(); 571 #endif /* DIAGNOSTIC */ 572 #endif 573 return (0); 574 } 575 576 /* XXX PRISON: could be per prison flag */ 577 static int prison_quotas; 578 #if 0 579 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 580 #endif 581 582 /* 583 * quotactl_args(char *path, int fcmd, int uid, caddr_t arg) 584 * 585 * Change filesystem quotas. 586 */ 587 /* ARGSUSED */ 588 int 589 quotactl(struct quotactl_args *uap) 590 { 591 struct thread *td = curthread; 592 struct proc *p = td->td_proc; 593 struct mount *mp; 594 int error; 595 struct nameidata nd; 596 597 KKASSERT(p); 598 if (p->p_ucred->cr_prison && !prison_quotas) 599 return (EPERM); 600 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 601 SCARG(uap, path), td); 602 if ((error = namei(&nd)) != 0) 603 return (error); 604 mp = nd.ni_vp->v_mount; 605 NDFREE(&nd, NDF_ONLY_PNBUF); 606 vrele(nd.ni_vp); 607 return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid), 608 SCARG(uap, arg), td)); 609 } 610 611 /* 612 * statfs_args(char *path, struct statfs *buf) 613 * 614 * Get filesystem statistics. 615 */ 616 /* ARGSUSED */ 617 int 618 statfs(struct statfs_args *uap) 619 { 620 struct thread *td = curthread; 621 struct mount *mp; 622 struct statfs *sp; 623 int error; 624 struct nameidata nd; 625 struct statfs sb; 626 627 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 628 SCARG(uap, path), td); 629 if ((error = namei(&nd)) != 0) 630 return (error); 631 mp = nd.ni_vp->v_mount; 632 sp = &mp->mnt_stat; 633 NDFREE(&nd, NDF_ONLY_PNBUF); 634 vrele(nd.ni_vp); 635 error = VFS_STATFS(mp, sp, td); 636 if (error) 637 return (error); 638 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 639 if (suser(td)) { 640 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 641 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 642 sp = &sb; 643 } 644 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 645 } 646 647 /* 648 * fstatfs_args(int fd, struct statfs *buf) 649 * 650 * Get filesystem statistics. 651 */ 652 /* ARGSUSED */ 653 int 654 fstatfs(struct fstatfs_args *uap) 655 { 656 struct thread *td = curthread; 657 struct proc *p = td->td_proc; 658 struct file *fp; 659 struct mount *mp; 660 struct statfs *sp; 661 int error; 662 struct statfs sb; 663 664 KKASSERT(p); 665 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 666 return (error); 667 mp = ((struct vnode *)fp->f_data)->v_mount; 668 if (mp == NULL) 669 return (EBADF); 670 sp = &mp->mnt_stat; 671 error = VFS_STATFS(mp, sp, td); 672 if (error) 673 return (error); 674 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 675 if (suser(td)) { 676 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 677 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 678 sp = &sb; 679 } 680 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 681 } 682 683 /* 684 * getfsstat_args(struct statfs *buf, long bufsize, int flags) 685 * 686 * Get statistics on all filesystems. 687 */ 688 /* ARGSUSED */ 689 int 690 getfsstat(struct getfsstat_args *uap) 691 { 692 struct thread *td = curthread; 693 struct mount *mp, *nmp; 694 struct statfs *sp; 695 caddr_t sfsp; 696 long count, maxcount, error; 697 698 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs); 699 sfsp = (caddr_t)SCARG(uap, buf); 700 count = 0; 701 lwkt_gettoken(&mountlist_token); 702 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { 703 if (vfs_busy(mp, LK_NOWAIT, &mountlist_token, td)) { 704 nmp = TAILQ_NEXT(mp, mnt_list); 705 continue; 706 } 707 if (sfsp && count < maxcount) { 708 sp = &mp->mnt_stat; 709 /* 710 * If MNT_NOWAIT or MNT_LAZY is specified, do not 711 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 712 * overrides MNT_WAIT. 713 */ 714 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 || 715 (SCARG(uap, flags) & MNT_WAIT)) && 716 (error = VFS_STATFS(mp, sp, td))) { 717 lwkt_gettoken(&mountlist_token); 718 nmp = TAILQ_NEXT(mp, mnt_list); 719 vfs_unbusy(mp, td); 720 continue; 721 } 722 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 723 error = copyout((caddr_t)sp, sfsp, sizeof(*sp)); 724 if (error) { 725 vfs_unbusy(mp, td); 726 return (error); 727 } 728 sfsp += sizeof(*sp); 729 } 730 count++; 731 lwkt_gettoken(&mountlist_token); 732 nmp = TAILQ_NEXT(mp, mnt_list); 733 vfs_unbusy(mp, td); 734 } 735 lwkt_reltoken(&mountlist_token); 736 if (sfsp && count > maxcount) 737 uap->sysmsg_result = maxcount; 738 else 739 uap->sysmsg_result = count; 740 return (0); 741 } 742 743 /* 744 * fchdir_args(int fd) 745 * 746 * Change current working directory to a given file descriptor. 747 */ 748 /* ARGSUSED */ 749 int 750 fchdir(struct fchdir_args *uap) 751 { 752 struct thread *td = curthread; 753 struct proc *p = td->td_proc; 754 struct filedesc *fdp = p->p_fd; 755 struct vnode *vp, *tdp; 756 struct mount *mp; 757 struct file *fp; 758 int error; 759 760 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 761 return (error); 762 vp = (struct vnode *)fp->f_data; 763 VREF(vp); 764 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 765 if (vp->v_type != VDIR) 766 error = ENOTDIR; 767 else 768 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, td); 769 while (!error && (mp = vp->v_mountedhere) != NULL) { 770 if (vfs_busy(mp, 0, 0, td)) 771 continue; 772 error = VFS_ROOT(mp, &tdp); 773 vfs_unbusy(mp, td); 774 if (error) 775 break; 776 vput(vp); 777 vp = tdp; 778 } 779 if (error) { 780 vput(vp); 781 return (error); 782 } 783 VOP_UNLOCK(vp, 0, td); 784 vrele(fdp->fd_cdir); 785 fdp->fd_cdir = vp; 786 return (0); 787 } 788 789 /* 790 * chdir_args(char *path) 791 * 792 * Change current working directory (``.''). 793 */ 794 /* ARGSUSED */ 795 int 796 chdir(struct chdir_args *uap) 797 { 798 struct thread *td = curthread; 799 struct proc *p = td->td_proc; 800 struct filedesc *fdp = p->p_fd; 801 int error; 802 struct nameidata nd; 803 804 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 805 SCARG(uap, path), td); 806 if ((error = change_dir(&nd, td)) != 0) 807 return (error); 808 NDFREE(&nd, NDF_ONLY_PNBUF); 809 vrele(fdp->fd_cdir); 810 fdp->fd_cdir = nd.ni_vp; 811 return (0); 812 } 813 814 /* 815 * Helper function for raised chroot(2) security function: Refuse if 816 * any filedescriptors are open directories. 817 */ 818 static int 819 chroot_refuse_vdir_fds(fdp) 820 struct filedesc *fdp; 821 { 822 struct vnode *vp; 823 struct file *fp; 824 int error; 825 int fd; 826 827 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 828 error = getvnode(fdp, fd, &fp); 829 if (error) 830 continue; 831 vp = (struct vnode *)fp->f_data; 832 if (vp->v_type != VDIR) 833 continue; 834 return(EPERM); 835 } 836 return (0); 837 } 838 839 /* 840 * This sysctl determines if we will allow a process to chroot(2) if it 841 * has a directory open: 842 * 0: disallowed for all processes. 843 * 1: allowed for processes that were not already chroot(2)'ed. 844 * 2: allowed for all processes. 845 */ 846 847 static int chroot_allow_open_directories = 1; 848 849 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 850 &chroot_allow_open_directories, 0, ""); 851 852 /* 853 * chroot_args(char *path) 854 * 855 * Change notion of root (``/'') directory. 856 */ 857 /* ARGSUSED */ 858 int 859 chroot(struct chroot_args *uap) 860 { 861 struct thread *td = curthread; 862 struct proc *p = td->td_proc; 863 struct filedesc *fdp = p->p_fd; 864 int error; 865 struct nameidata nd; 866 867 KKASSERT(p); 868 error = suser_cred(p->p_ucred, PRISON_ROOT); 869 if (error) 870 return (error); 871 if (chroot_allow_open_directories == 0 || 872 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) 873 error = chroot_refuse_vdir_fds(fdp); 874 if (error) 875 return (error); 876 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 877 SCARG(uap, path), td); 878 if ((error = change_dir(&nd, td)) != 0) 879 return (error); 880 NDFREE(&nd, NDF_ONLY_PNBUF); 881 vrele(fdp->fd_rdir); 882 fdp->fd_rdir = nd.ni_vp; 883 if (!fdp->fd_jdir) { 884 fdp->fd_jdir = nd.ni_vp; 885 VREF(fdp->fd_jdir); 886 } 887 return (0); 888 } 889 890 /* 891 * Common routine for chroot and chdir. 892 */ 893 static int 894 change_dir(struct nameidata *ndp, struct thread *td) 895 { 896 struct vnode *vp; 897 int error; 898 899 error = namei(ndp); 900 if (error) 901 return (error); 902 vp = ndp->ni_vp; 903 if (vp->v_type != VDIR) 904 error = ENOTDIR; 905 else 906 error = VOP_ACCESS(vp, VEXEC, ndp->ni_cnd.cn_cred, td); 907 if (error) 908 vput(vp); 909 else 910 VOP_UNLOCK(vp, 0, td); 911 return (error); 912 } 913 914 /* 915 * open_args(char *path, int flags, int mode) 916 * 917 * Check permissions, allocate an open file structure, 918 * and call the device open routine if any. 919 */ 920 int 921 open(struct open_args *uap) 922 { 923 struct thread *td = curthread; 924 struct proc *p = td->td_proc; 925 struct filedesc *fdp = p->p_fd; 926 struct file *fp; 927 struct vnode *vp; 928 int cmode, flags, oflags; 929 struct file *nfp; 930 int type, indx, error; 931 struct flock lf; 932 struct nameidata nd; 933 934 oflags = SCARG(uap, flags); 935 if ((oflags & O_ACCMODE) == O_ACCMODE) 936 return (EINVAL); 937 flags = FFLAGS(oflags); 938 error = falloc(p, &nfp, &indx); 939 if (error) 940 return (error); 941 fp = nfp; 942 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 943 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 944 SCARG(uap, path), td); 945 p->p_dupfd = -indx - 1; /* XXX check for fdopen */ 946 /* 947 * Bump the ref count to prevent another process from closing 948 * the descriptor while we are blocked in vn_open() 949 */ 950 fhold(fp); 951 error = vn_open(&nd, flags, cmode); 952 if (error) { 953 /* 954 * release our own reference 955 */ 956 fdrop(fp, td); 957 958 /* 959 * handle special fdopen() case. bleh. dupfdopen() is 960 * responsible for dropping the old contents of ofiles[indx] 961 * if it succeeds. 962 */ 963 if ((error == ENODEV || error == ENXIO) && 964 p->p_dupfd >= 0 && /* XXX from fdopen */ 965 (error = 966 dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) { 967 uap->sysmsg_result = indx; 968 return (0); 969 } 970 /* 971 * Clean up the descriptor, but only if another thread hadn't 972 * replaced or closed it. 973 */ 974 if (fdp->fd_ofiles[indx] == fp) { 975 fdp->fd_ofiles[indx] = NULL; 976 fdrop(fp, td); 977 } 978 979 if (error == ERESTART) 980 error = EINTR; 981 return (error); 982 } 983 p->p_dupfd = 0; 984 NDFREE(&nd, NDF_ONLY_PNBUF); 985 vp = nd.ni_vp; 986 987 /* 988 * There should be 2 references on the file, one from the descriptor 989 * table, and one for us. 990 * 991 * Handle the case where someone closed the file (via its file 992 * descriptor) while we were blocked. The end result should look 993 * like opening the file succeeded but it was immediately closed. 994 */ 995 if (fp->f_count == 1) { 996 KASSERT(fdp->fd_ofiles[indx] != fp, 997 ("Open file descriptor lost all refs")); 998 VOP_UNLOCK(vp, 0, td); 999 vn_close(vp, flags & FMASK, td); 1000 fdrop(fp, td); 1001 uap->sysmsg_result = indx; 1002 return 0; 1003 } 1004 1005 fp->f_data = (caddr_t)vp; 1006 fp->f_flag = flags & FMASK; 1007 fp->f_ops = &vnops; 1008 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); 1009 if (flags & (O_EXLOCK | O_SHLOCK)) { 1010 lf.l_whence = SEEK_SET; 1011 lf.l_start = 0; 1012 lf.l_len = 0; 1013 if (flags & O_EXLOCK) 1014 lf.l_type = F_WRLCK; 1015 else 1016 lf.l_type = F_RDLCK; 1017 type = F_FLOCK; 1018 if ((flags & FNONBLOCK) == 0) 1019 type |= F_WAIT; 1020 VOP_UNLOCK(vp, 0, td); 1021 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 1022 /* 1023 * lock request failed. Normally close the descriptor 1024 * but handle the case where someone might have dup()d 1025 * it when we weren't looking. One reference is 1026 * owned by the descriptor array, the other by us. 1027 */ 1028 if (fdp->fd_ofiles[indx] == fp) { 1029 fdp->fd_ofiles[indx] = NULL; 1030 fdrop(fp, td); 1031 } 1032 fdrop(fp, td); 1033 return (error); 1034 } 1035 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1036 fp->f_flag |= FHASLOCK; 1037 } 1038 /* assert that vn_open created a backing object if one is needed */ 1039 KASSERT(!vn_canvmio(vp) || VOP_GETVOBJECT(vp, NULL) == 0, 1040 ("open: vmio vnode has no backing object after vn_open")); 1041 VOP_UNLOCK(vp, 0, td); 1042 1043 /* 1044 * release our private reference, leaving the one associated with the 1045 * descriptor table intact. 1046 */ 1047 fdrop(fp, td); 1048 uap->sysmsg_result = indx; 1049 return (0); 1050 } 1051 1052 #ifdef COMPAT_43 1053 /* 1054 * ocreat(char *path, int mode) 1055 * 1056 * Create a file. 1057 */ 1058 int 1059 ocreat(struct ocreat_args *uap) 1060 { 1061 struct open_args /* { 1062 syscallarg(char *) path; 1063 syscallarg(int) flags; 1064 syscallarg(int) mode; 1065 } */ nuap; 1066 1067 SCARG(&nuap, path) = SCARG(uap, path); 1068 SCARG(&nuap, mode) = SCARG(uap, mode); 1069 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; 1070 return (open(&nuap)); 1071 } 1072 #endif /* COMPAT_43 */ 1073 1074 /* 1075 * mknod_args(char *path, int mode, int dev) 1076 * 1077 * Create a special file. 1078 */ 1079 /* ARGSUSED */ 1080 int 1081 mknod(struct mknod_args *uap) 1082 { 1083 struct thread *td = curthread; 1084 struct proc *p = td->td_proc; 1085 struct vnode *vp; 1086 struct vattr vattr; 1087 int error; 1088 int whiteout = 0; 1089 struct nameidata nd; 1090 1091 KKASSERT(p); 1092 1093 switch (SCARG(uap, mode) & S_IFMT) { 1094 case S_IFCHR: 1095 case S_IFBLK: 1096 error = suser(td); 1097 break; 1098 default: 1099 error = suser_cred(p->p_ucred, PRISON_ROOT); 1100 break; 1101 } 1102 if (error) 1103 return (error); 1104 bwillwrite(); 1105 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, 1106 SCARG(uap, path), td); 1107 if ((error = namei(&nd)) != 0) 1108 return (error); 1109 vp = nd.ni_vp; 1110 if (vp != NULL) 1111 error = EEXIST; 1112 else { 1113 VATTR_NULL(&vattr); 1114 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1115 vattr.va_rdev = SCARG(uap, dev); 1116 whiteout = 0; 1117 1118 switch (SCARG(uap, mode) & S_IFMT) { 1119 case S_IFMT: /* used by badsect to flag bad sectors */ 1120 vattr.va_type = VBAD; 1121 break; 1122 case S_IFCHR: 1123 vattr.va_type = VCHR; 1124 break; 1125 case S_IFBLK: 1126 vattr.va_type = VBLK; 1127 break; 1128 case S_IFWHT: 1129 whiteout = 1; 1130 break; 1131 default: 1132 error = EINVAL; 1133 break; 1134 } 1135 } 1136 if (!error) { 1137 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 1138 if (whiteout) 1139 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, NAMEI_CREATE); 1140 else { 1141 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1142 &nd.ni_cnd, &vattr); 1143 if (error == 0) 1144 vput(nd.ni_vp); 1145 } 1146 NDFREE(&nd, NDF_ONLY_PNBUF); 1147 vput(nd.ni_dvp); 1148 } else { 1149 NDFREE(&nd, NDF_ONLY_PNBUF); 1150 if (nd.ni_dvp == vp) 1151 vrele(nd.ni_dvp); 1152 else 1153 vput(nd.ni_dvp); 1154 if (vp) 1155 vrele(vp); 1156 } 1157 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); 1158 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); 1159 return (error); 1160 } 1161 1162 /* 1163 * mkfifo_args(char *path, int mode) 1164 * 1165 * Create a named pipe. 1166 */ 1167 /* ARGSUSED */ 1168 int 1169 mkfifo(struct mkfifo_args *uap) 1170 { 1171 struct thread *td = curthread; 1172 struct proc *p = td->td_proc; 1173 struct vattr vattr; 1174 int error; 1175 struct nameidata nd; 1176 1177 bwillwrite(); 1178 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, 1179 SCARG(uap, path), td); 1180 if ((error = namei(&nd)) != 0) 1181 return (error); 1182 if (nd.ni_vp != NULL) { 1183 NDFREE(&nd, NDF_ONLY_PNBUF); 1184 if (nd.ni_dvp == nd.ni_vp) 1185 vrele(nd.ni_dvp); 1186 else 1187 vput(nd.ni_dvp); 1188 vrele(nd.ni_vp); 1189 return (EEXIST); 1190 } 1191 VATTR_NULL(&vattr); 1192 vattr.va_type = VFIFO; 1193 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1194 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 1195 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1196 if (error == 0) 1197 vput(nd.ni_vp); 1198 NDFREE(&nd, NDF_ONLY_PNBUF); 1199 vput(nd.ni_dvp); 1200 return (error); 1201 } 1202 1203 /* 1204 * link_args(char *path, char *link) 1205 * 1206 * Make a hard file link. 1207 */ 1208 /* ARGSUSED */ 1209 int 1210 link(struct link_args *uap) 1211 { 1212 struct thread *td = curthread; 1213 struct proc *p = td->td_proc; 1214 struct vnode *vp; 1215 struct nameidata nd; 1216 int error; 1217 1218 bwillwrite(); 1219 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_NOOBJ, UIO_USERSPACE, 1220 SCARG(uap, path), td); 1221 if ((error = namei(&nd)) != 0) 1222 return (error); 1223 NDFREE(&nd, NDF_ONLY_PNBUF); 1224 vp = nd.ni_vp; 1225 if (vp->v_type == VDIR) 1226 error = EPERM; /* POSIX */ 1227 else { 1228 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, 1229 UIO_USERSPACE, SCARG(uap, link), td); 1230 error = namei(&nd); 1231 if (!error) { 1232 if (nd.ni_vp != NULL) { 1233 if (nd.ni_vp) 1234 vrele(nd.ni_vp); 1235 error = EEXIST; 1236 } else { 1237 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, 1238 LEASE_WRITE); 1239 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1240 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1241 } 1242 NDFREE(&nd, NDF_ONLY_PNBUF); 1243 if (nd.ni_dvp == nd.ni_vp) 1244 vrele(nd.ni_dvp); 1245 else 1246 vput(nd.ni_dvp); 1247 } 1248 } 1249 vrele(vp); 1250 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); 1251 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); 1252 return (error); 1253 } 1254 1255 /* 1256 * symlink(char *path, char *link) 1257 * 1258 * Make a symbolic link. 1259 */ 1260 /* ARGSUSED */ 1261 int 1262 symlink(struct symlink_args *uap) 1263 { 1264 struct thread *td = curthread; 1265 struct proc *p = td->td_proc; 1266 struct vattr vattr; 1267 char *path; 1268 int error; 1269 struct nameidata nd; 1270 1271 path = zalloc(namei_zone); 1272 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) 1273 goto out; 1274 bwillwrite(); 1275 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, UIO_USERSPACE, 1276 SCARG(uap, link), td); 1277 if ((error = namei(&nd)) != 0) 1278 goto out; 1279 if (nd.ni_vp) { 1280 NDFREE(&nd, NDF_ONLY_PNBUF); 1281 if (nd.ni_dvp == nd.ni_vp) 1282 vrele(nd.ni_dvp); 1283 else 1284 vput(nd.ni_dvp); 1285 vrele(nd.ni_vp); 1286 error = EEXIST; 1287 goto out; 1288 } 1289 VATTR_NULL(&vattr); 1290 vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; 1291 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 1292 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); 1293 NDFREE(&nd, NDF_ONLY_PNBUF); 1294 if (error == 0) 1295 vput(nd.ni_vp); 1296 vput(nd.ni_dvp); 1297 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); 1298 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); 1299 out: 1300 zfree(namei_zone, path); 1301 return (error); 1302 } 1303 1304 /* 1305 * undelete_args(char *path) 1306 * 1307 * Delete a whiteout from the filesystem. 1308 */ 1309 /* ARGSUSED */ 1310 int 1311 undelete(struct undelete_args *uap) 1312 { 1313 struct thread *td = curthread; 1314 struct proc *p = td->td_proc; 1315 int error; 1316 struct nameidata nd; 1317 1318 bwillwrite(); 1319 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_DOWHITEOUT, UIO_USERSPACE, 1320 SCARG(uap, path), td); 1321 error = namei(&nd); 1322 if (error) 1323 return (error); 1324 1325 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & CNP_ISWHITEOUT)) { 1326 NDFREE(&nd, NDF_ONLY_PNBUF); 1327 if (nd.ni_dvp == nd.ni_vp) 1328 vrele(nd.ni_dvp); 1329 else 1330 vput(nd.ni_dvp); 1331 if (nd.ni_vp) 1332 vrele(nd.ni_vp); 1333 return (EEXIST); 1334 } 1335 1336 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 1337 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, NAMEI_DELETE); 1338 NDFREE(&nd, NDF_ONLY_PNBUF); 1339 vput(nd.ni_dvp); 1340 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); 1341 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); 1342 return (error); 1343 } 1344 1345 /* 1346 * unlink_args(char *path) 1347 * 1348 * Delete a name from the filesystem. 1349 */ 1350 int 1351 unlink(struct unlink_args *uap) 1352 { 1353 struct thread *td = curthread; 1354 struct proc *p = td->td_proc; 1355 struct vnode *vp; 1356 int error; 1357 struct nameidata nd; 1358 1359 bwillwrite(); 1360 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td); 1361 if ((error = namei(&nd)) != 0) 1362 return (error); 1363 vp = nd.ni_vp; 1364 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1365 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1366 1367 if (vp->v_type == VDIR) 1368 error = EPERM; /* POSIX */ 1369 else { 1370 /* 1371 * The root of a mounted filesystem cannot be deleted. 1372 * 1373 * XXX: can this only be a VDIR case? 1374 */ 1375 if (vp->v_flag & VROOT) 1376 error = EBUSY; 1377 } 1378 1379 if (!error) { 1380 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 1381 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1382 } 1383 NDFREE(&nd, NDF_ONLY_PNBUF); 1384 if (nd.ni_dvp == vp) 1385 vrele(nd.ni_dvp); 1386 else 1387 vput(nd.ni_dvp); 1388 if (vp != NULLVP) 1389 vput(vp); 1390 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); 1391 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); 1392 return (error); 1393 } 1394 1395 /* 1396 * lseek_args(int fd, int pad, off_t offset, int whence) 1397 * 1398 * Reposition read/write file offset. 1399 */ 1400 int 1401 lseek(struct lseek_args *uap) 1402 { 1403 struct thread *td = curthread; 1404 struct proc *p = td->td_proc; 1405 struct filedesc *fdp = p->p_fd; 1406 struct file *fp; 1407 struct vattr vattr; 1408 int error; 1409 1410 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 1411 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) 1412 return (EBADF); 1413 if (fp->f_type != DTYPE_VNODE) 1414 return (ESPIPE); 1415 switch (SCARG(uap, whence)) { 1416 case L_INCR: 1417 fp->f_offset += SCARG(uap, offset); 1418 break; 1419 case L_XTND: 1420 error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, td); 1421 if (error) 1422 return (error); 1423 fp->f_offset = SCARG(uap, offset) + vattr.va_size; 1424 break; 1425 case L_SET: 1426 fp->f_offset = SCARG(uap, offset); 1427 break; 1428 default: 1429 return (EINVAL); 1430 } 1431 uap->sysmsg_offset = fp->f_offset; 1432 return (0); 1433 } 1434 1435 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1436 /* 1437 * Reposition read/write file offset. 1438 * 1439 * olseek_args(int fd, long offset, int whence) 1440 */ 1441 int 1442 olseek(struct olseek_args *uap) 1443 { 1444 struct lseek_args /* { 1445 syscallarg(int) fd; 1446 syscallarg(int) pad; 1447 syscallarg(off_t) offset; 1448 syscallarg(int) whence; 1449 } */ nuap; 1450 int error; 1451 1452 SCARG(&nuap, fd) = SCARG(uap, fd); 1453 SCARG(&nuap, offset) = SCARG(uap, offset); 1454 SCARG(&nuap, whence) = SCARG(uap, whence); 1455 error = lseek(&nuap); 1456 return (error); 1457 } 1458 #endif /* COMPAT_43 */ 1459 1460 /* 1461 * access_args(char *path, int flags) 1462 * 1463 * Check access permissions. 1464 */ 1465 int 1466 access(struct access_args *uap) 1467 { 1468 struct thread *td = curthread; 1469 struct proc *p = td->td_proc; 1470 struct ucred *cred, *tmpcred; 1471 struct vnode *vp; 1472 int error, flags; 1473 struct nameidata nd; 1474 1475 cred = p->p_ucred; 1476 /* 1477 * Create and modify a temporary credential instead of one that 1478 * is potentially shared. This could also mess up socket 1479 * buffer accounting which can run in an interrupt context. 1480 */ 1481 tmpcred = crdup(cred); 1482 tmpcred->cr_uid = p->p_ucred->cr_ruid; 1483 tmpcred->cr_groups[0] = p->p_ucred->cr_rgid; 1484 p->p_ucred = tmpcred; 1485 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, 1486 UIO_USERSPACE, SCARG(uap, path), td); 1487 if ((error = namei(&nd)) != 0) 1488 goto out1; 1489 vp = nd.ni_vp; 1490 1491 /* Flags == 0 means only check for existence. */ 1492 if (SCARG(uap, flags)) { 1493 flags = 0; 1494 if (SCARG(uap, flags) & R_OK) 1495 flags |= VREAD; 1496 if (SCARG(uap, flags) & W_OK) 1497 flags |= VWRITE; 1498 if (SCARG(uap, flags) & X_OK) 1499 flags |= VEXEC; 1500 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 1501 error = VOP_ACCESS(vp, flags, tmpcred, td); 1502 } 1503 NDFREE(&nd, NDF_ONLY_PNBUF); 1504 vput(vp); 1505 out1: 1506 p->p_ucred = cred; 1507 crfree(tmpcred); 1508 return (error); 1509 } 1510 1511 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1512 /* 1513 * ostat_args(char *path, struct ostat *ub) 1514 * 1515 * Get file status; this version follows links. 1516 */ 1517 /* ARGSUSED */ 1518 int 1519 ostat(struct ostat_args *uap) 1520 { 1521 struct thread *td = curthread; 1522 struct stat sb; 1523 struct ostat osb; 1524 int error; 1525 struct nameidata nd; 1526 1527 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, 1528 UIO_USERSPACE, SCARG(uap, path), td); 1529 if ((error = namei(&nd)) != 0) 1530 return (error); 1531 NDFREE(&nd, NDF_ONLY_PNBUF); 1532 error = vn_stat(nd.ni_vp, &sb, td); 1533 vput(nd.ni_vp); 1534 if (error) 1535 return (error); 1536 cvtstat(&sb, &osb); 1537 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1538 return (error); 1539 } 1540 1541 /* 1542 * olstat_args(char *path, struct ostat *ub) 1543 * 1544 * Get file status; this version does not follow links. 1545 */ 1546 /* ARGSUSED */ 1547 int 1548 olstat(struct olstat_args *uap) 1549 { 1550 struct thread *td = curthread; 1551 struct vnode *vp; 1552 struct stat sb; 1553 struct ostat osb; 1554 int error; 1555 struct nameidata nd; 1556 1557 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, 1558 UIO_USERSPACE, SCARG(uap, path), td); 1559 if ((error = namei(&nd)) != 0) 1560 return (error); 1561 vp = nd.ni_vp; 1562 error = vn_stat(vp, &sb, td); 1563 NDFREE(&nd, NDF_ONLY_PNBUF); 1564 vput(vp); 1565 if (error) 1566 return (error); 1567 cvtstat(&sb, &osb); 1568 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1569 return (error); 1570 } 1571 1572 /* 1573 * Convert from an old to a new stat structure. 1574 */ 1575 void 1576 cvtstat(st, ost) 1577 struct stat *st; 1578 struct ostat *ost; 1579 { 1580 ost->st_dev = st->st_dev; 1581 ost->st_ino = st->st_ino; 1582 ost->st_mode = st->st_mode; 1583 ost->st_nlink = st->st_nlink; 1584 ost->st_uid = st->st_uid; 1585 ost->st_gid = st->st_gid; 1586 ost->st_rdev = st->st_rdev; 1587 if (st->st_size < (quad_t)1 << 32) 1588 ost->st_size = st->st_size; 1589 else 1590 ost->st_size = -2; 1591 ost->st_atime = st->st_atime; 1592 ost->st_mtime = st->st_mtime; 1593 ost->st_ctime = st->st_ctime; 1594 ost->st_blksize = st->st_blksize; 1595 ost->st_blocks = st->st_blocks; 1596 ost->st_flags = st->st_flags; 1597 ost->st_gen = st->st_gen; 1598 } 1599 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1600 1601 /* 1602 * stat_args(char *path, struct stat *ub) 1603 * 1604 * Get file status; this version follows links. 1605 */ 1606 /* ARGSUSED */ 1607 int 1608 stat(struct stat_args *uap) 1609 { 1610 struct thread *td = curthread; 1611 struct stat sb; 1612 int error; 1613 struct nameidata nd; 1614 1615 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, 1616 UIO_USERSPACE, SCARG(uap, path), td); 1617 if ((error = namei(&nd)) != 0) 1618 return (error); 1619 error = vn_stat(nd.ni_vp, &sb, td); 1620 NDFREE(&nd, NDF_ONLY_PNBUF); 1621 vput(nd.ni_vp); 1622 if (error) 1623 return (error); 1624 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1625 return (error); 1626 } 1627 1628 /* 1629 * lstat_args(char *path, struct stat *ub) 1630 * 1631 * Get file status; this version does not follow links. 1632 */ 1633 /* ARGSUSED */ 1634 int 1635 lstat(struct lstat_args *uap) 1636 { 1637 struct thread *td = curthread; 1638 int error; 1639 struct vnode *vp; 1640 struct stat sb; 1641 struct nameidata nd; 1642 1643 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, 1644 UIO_USERSPACE, SCARG(uap, path), td); 1645 if ((error = namei(&nd)) != 0) 1646 return (error); 1647 vp = nd.ni_vp; 1648 error = vn_stat(vp, &sb, td); 1649 NDFREE(&nd, NDF_ONLY_PNBUF); 1650 vput(vp); 1651 if (error) 1652 return (error); 1653 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1654 return (error); 1655 } 1656 1657 void 1658 cvtnstat(sb, nsb) 1659 struct stat *sb; 1660 struct nstat *nsb; 1661 { 1662 nsb->st_dev = sb->st_dev; 1663 nsb->st_ino = sb->st_ino; 1664 nsb->st_mode = sb->st_mode; 1665 nsb->st_nlink = sb->st_nlink; 1666 nsb->st_uid = sb->st_uid; 1667 nsb->st_gid = sb->st_gid; 1668 nsb->st_rdev = sb->st_rdev; 1669 nsb->st_atimespec = sb->st_atimespec; 1670 nsb->st_mtimespec = sb->st_mtimespec; 1671 nsb->st_ctimespec = sb->st_ctimespec; 1672 nsb->st_size = sb->st_size; 1673 nsb->st_blocks = sb->st_blocks; 1674 nsb->st_blksize = sb->st_blksize; 1675 nsb->st_flags = sb->st_flags; 1676 nsb->st_gen = sb->st_gen; 1677 nsb->st_qspare[0] = sb->st_qspare[0]; 1678 nsb->st_qspare[1] = sb->st_qspare[1]; 1679 } 1680 1681 /* 1682 * nstat_args(char *path, struct nstat *ub) 1683 */ 1684 /* ARGSUSED */ 1685 int 1686 nstat(struct nstat_args *uap) 1687 { 1688 struct thread *td = curthread; 1689 struct stat sb; 1690 struct nstat nsb; 1691 int error; 1692 struct nameidata nd; 1693 1694 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, 1695 UIO_USERSPACE, SCARG(uap, path), td); 1696 if ((error = namei(&nd)) != 0) 1697 return (error); 1698 NDFREE(&nd, NDF_ONLY_PNBUF); 1699 error = vn_stat(nd.ni_vp, &sb, td); 1700 vput(nd.ni_vp); 1701 if (error) 1702 return (error); 1703 cvtnstat(&sb, &nsb); 1704 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1705 return (error); 1706 } 1707 1708 /* 1709 * lstat_args(char *path, struct stat *ub) 1710 * 1711 * Get file status; this version does not follow links. 1712 */ 1713 /* ARGSUSED */ 1714 int 1715 nlstat(struct nlstat_args *uap) 1716 { 1717 struct thread *td = curthread; 1718 int error; 1719 struct vnode *vp; 1720 struct stat sb; 1721 struct nstat nsb; 1722 struct nameidata nd; 1723 1724 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, 1725 UIO_USERSPACE, SCARG(uap, path), td); 1726 if ((error = namei(&nd)) != 0) 1727 return (error); 1728 vp = nd.ni_vp; 1729 NDFREE(&nd, NDF_ONLY_PNBUF); 1730 error = vn_stat(vp, &sb, td); 1731 vput(vp); 1732 if (error) 1733 return (error); 1734 cvtnstat(&sb, &nsb); 1735 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1736 return (error); 1737 } 1738 1739 /* 1740 * pathconf_Args(char *path, int name) 1741 * 1742 * Get configurable pathname variables. 1743 */ 1744 /* ARGSUSED */ 1745 int 1746 pathconf(struct pathconf_args *uap) 1747 { 1748 struct thread *td = curthread; 1749 int error; 1750 struct nameidata nd; 1751 1752 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, 1753 UIO_USERSPACE, SCARG(uap, path), td); 1754 if ((error = namei(&nd)) != 0) 1755 return (error); 1756 NDFREE(&nd, NDF_ONLY_PNBUF); 1757 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), uap->sysmsg_fds); 1758 vput(nd.ni_vp); 1759 return (error); 1760 } 1761 1762 /* 1763 * readlink_args(char *path, char *buf, int count) 1764 * 1765 * Return target name of a symbolic link. 1766 */ 1767 /* ARGSUSED */ 1768 int 1769 readlink(struct readlink_args *uap) 1770 { 1771 struct thread *td = curthread; 1772 struct proc *p = td->td_proc; 1773 struct vnode *vp; 1774 struct iovec aiov; 1775 struct uio auio; 1776 int error; 1777 struct nameidata nd; 1778 1779 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, 1780 UIO_USERSPACE, SCARG(uap, path), td); 1781 if ((error = namei(&nd)) != 0) 1782 return (error); 1783 NDFREE(&nd, NDF_ONLY_PNBUF); 1784 vp = nd.ni_vp; 1785 if (vp->v_type != VLNK) 1786 error = EINVAL; 1787 else { 1788 aiov.iov_base = SCARG(uap, buf); 1789 aiov.iov_len = SCARG(uap, count); 1790 auio.uio_iov = &aiov; 1791 auio.uio_iovcnt = 1; 1792 auio.uio_offset = 0; 1793 auio.uio_rw = UIO_READ; 1794 auio.uio_segflg = UIO_USERSPACE; 1795 auio.uio_td = td; 1796 auio.uio_resid = SCARG(uap, count); 1797 error = VOP_READLINK(vp, &auio, p->p_ucred); 1798 } 1799 vput(vp); 1800 uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; 1801 return (error); 1802 } 1803 1804 static int 1805 setfflags(struct vnode *vp, int flags) 1806 { 1807 struct thread *td = curthread; 1808 struct proc *p = td->td_proc; 1809 int error; 1810 struct vattr vattr; 1811 1812 /* 1813 * Prevent non-root users from setting flags on devices. When 1814 * a device is reused, users can retain ownership of the device 1815 * if they are allowed to set flags and programs assume that 1816 * chown can't fail when done as root. 1817 */ 1818 if ((vp->v_type == VCHR || vp->v_type == VBLK) && 1819 ((error = suser_cred(p->p_ucred, PRISON_ROOT)) != 0)) 1820 return (error); 1821 1822 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1823 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1824 VATTR_NULL(&vattr); 1825 vattr.va_flags = flags; 1826 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1827 VOP_UNLOCK(vp, 0, td); 1828 return (error); 1829 } 1830 1831 /* 1832 * chflags(char *path, int flags) 1833 * 1834 * Change flags of a file given a path name. 1835 */ 1836 /* ARGSUSED */ 1837 int 1838 chflags(struct chflags_args *uap) 1839 { 1840 struct thread *td = curthread; 1841 int error; 1842 struct nameidata nd; 1843 1844 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 1845 SCARG(uap, path), td); 1846 if ((error = namei(&nd)) != 0) 1847 return (error); 1848 NDFREE(&nd, NDF_ONLY_PNBUF); 1849 error = setfflags(nd.ni_vp, SCARG(uap, flags)); 1850 vrele(nd.ni_vp); 1851 return error; 1852 } 1853 1854 /* 1855 * fchflags_args(int fd, int flags) 1856 * 1857 * Change flags of a file given a file descriptor. 1858 */ 1859 /* ARGSUSED */ 1860 int 1861 fchflags(struct fchflags_args *uap) 1862 { 1863 struct thread *td = curthread; 1864 struct proc *p = td->td_proc; 1865 struct file *fp; 1866 int error; 1867 1868 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1869 return (error); 1870 return setfflags((struct vnode *) fp->f_data, SCARG(uap, flags)); 1871 } 1872 1873 static int 1874 setfmode(struct vnode *vp, int mode) 1875 { 1876 struct thread *td = curthread; 1877 struct proc *p = td->td_proc; 1878 int error; 1879 struct vattr vattr; 1880 1881 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1882 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1883 VATTR_NULL(&vattr); 1884 vattr.va_mode = mode & ALLPERMS; 1885 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1886 VOP_UNLOCK(vp, 0, td); 1887 return error; 1888 } 1889 1890 /* 1891 * chmod_args(char *path, int mode) 1892 * 1893 * Change mode of a file given path name. 1894 */ 1895 /* ARGSUSED */ 1896 int 1897 chmod(struct chmod_args *uap) 1898 { 1899 struct thread *td = curthread; 1900 int error; 1901 struct nameidata nd; 1902 1903 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 1904 SCARG(uap, path), td); 1905 if ((error = namei(&nd)) != 0) 1906 return (error); 1907 NDFREE(&nd, NDF_ONLY_PNBUF); 1908 error = setfmode(nd.ni_vp, SCARG(uap, mode)); 1909 vrele(nd.ni_vp); 1910 return error; 1911 } 1912 1913 /* 1914 * lchmod_args(char *path, int mode) 1915 * 1916 * Change mode of a file given path name (don't follow links.) 1917 */ 1918 /* ARGSUSED */ 1919 int 1920 lchmod(struct lchmod_args *uap) 1921 { 1922 struct thread *td = curthread; 1923 int error; 1924 struct nameidata nd; 1925 1926 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); 1927 if ((error = namei(&nd)) != 0) 1928 return (error); 1929 NDFREE(&nd, NDF_ONLY_PNBUF); 1930 error = setfmode(nd.ni_vp, SCARG(uap, mode)); 1931 vrele(nd.ni_vp); 1932 return error; 1933 } 1934 1935 /* 1936 * fchmod_args(int fd, int mode) 1937 * 1938 * Change mode of a file given a file descriptor. 1939 */ 1940 /* ARGSUSED */ 1941 int 1942 fchmod(struct fchmod_args *uap) 1943 { 1944 struct thread *td = curthread; 1945 struct proc *p = td->td_proc; 1946 struct file *fp; 1947 int error; 1948 1949 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1950 return (error); 1951 return setfmode((struct vnode *)fp->f_data, SCARG(uap, mode)); 1952 } 1953 1954 static int 1955 setfown(struct vnode *vp, uid_t uid, gid_t gid) 1956 { 1957 struct thread *td = curthread; 1958 struct proc *p = td->td_proc; 1959 int error; 1960 struct vattr vattr; 1961 1962 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1963 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1964 VATTR_NULL(&vattr); 1965 vattr.va_uid = uid; 1966 vattr.va_gid = gid; 1967 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1968 VOP_UNLOCK(vp, 0, td); 1969 return error; 1970 } 1971 1972 /* 1973 * chown(char *path, int uid, int gid) 1974 * 1975 * Set ownership given a path name. 1976 */ 1977 /* ARGSUSED */ 1978 int 1979 chown(struct chown_args *uap) 1980 { 1981 struct thread *td = curthread; 1982 int error; 1983 struct nameidata nd; 1984 1985 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 1986 SCARG(uap, path), td); 1987 if ((error = namei(&nd)) != 0) 1988 return (error); 1989 NDFREE(&nd, NDF_ONLY_PNBUF); 1990 error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 1991 vrele(nd.ni_vp); 1992 return (error); 1993 } 1994 1995 /* 1996 * lchown_args(char *path, int uid, int gid) 1997 * 1998 * Set ownership given a path name, do not cross symlinks. 1999 */ 2000 /* ARGSUSED */ 2001 int 2002 lchown(struct lchown_args *uap) 2003 { 2004 struct thread *td = curthread; 2005 int error; 2006 struct nameidata nd; 2007 2008 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); 2009 if ((error = namei(&nd)) != 0) 2010 return (error); 2011 NDFREE(&nd, NDF_ONLY_PNBUF); 2012 error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2013 vrele(nd.ni_vp); 2014 return (error); 2015 } 2016 2017 /* 2018 * fchown_args(int fd, int uid, int gid) 2019 * 2020 * Set ownership given a file descriptor. 2021 */ 2022 /* ARGSUSED */ 2023 int 2024 fchown(struct fchown_args *uap) 2025 { 2026 struct thread *td = curthread; 2027 struct proc *p = td->td_proc; 2028 struct file *fp; 2029 int error; 2030 2031 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2032 return (error); 2033 return setfown((struct vnode *)fp->f_data, 2034 SCARG(uap, uid), SCARG(uap, gid)); 2035 } 2036 2037 static int 2038 getutimes(const struct timeval *usrtvp, struct timespec *tsp) 2039 { 2040 struct timeval tv[2]; 2041 int error; 2042 2043 if (usrtvp == NULL) { 2044 microtime(&tv[0]); 2045 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2046 tsp[1] = tsp[0]; 2047 } else { 2048 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0) 2049 return (error); 2050 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2051 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]); 2052 } 2053 return 0; 2054 } 2055 2056 static int 2057 setutimes(struct vnode *vp, const struct timespec *ts, int nullflag) 2058 { 2059 struct thread *td = curthread; 2060 struct proc *p = td->td_proc; 2061 int error; 2062 struct vattr vattr; 2063 2064 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2065 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2066 VATTR_NULL(&vattr); 2067 vattr.va_atime = ts[0]; 2068 vattr.va_mtime = ts[1]; 2069 if (nullflag) 2070 vattr.va_vaflags |= VA_UTIMES_NULL; 2071 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 2072 VOP_UNLOCK(vp, 0, td); 2073 return error; 2074 } 2075 2076 /* 2077 * utimes_args(char *path, struct timeval *tptr) 2078 * 2079 * Set the access and modification times of a file. 2080 */ 2081 /* ARGSUSED */ 2082 int 2083 utimes(struct utimes_args *uap) 2084 { 2085 struct thread *td = curthread; 2086 struct timespec ts[2]; 2087 struct timeval *usrtvp; 2088 int error; 2089 struct nameidata nd; 2090 2091 usrtvp = SCARG(uap, tptr); 2092 if ((error = getutimes(usrtvp, ts)) != 0) 2093 return (error); 2094 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 2095 if ((error = namei(&nd)) != 0) 2096 return (error); 2097 NDFREE(&nd, NDF_ONLY_PNBUF); 2098 error = setutimes(nd.ni_vp, ts, usrtvp == NULL); 2099 vrele(nd.ni_vp); 2100 return (error); 2101 } 2102 2103 /* 2104 * lutimes_args(char *path, struct timeval *tptr) 2105 * 2106 * Set the access and modification times of a file. 2107 */ 2108 /* ARGSUSED */ 2109 int 2110 lutimes(struct lutimes_args *uap) 2111 { 2112 struct thread *td = curthread; 2113 struct timespec ts[2]; 2114 struct timeval *usrtvp; 2115 int error; 2116 struct nameidata nd; 2117 2118 usrtvp = SCARG(uap, tptr); 2119 if ((error = getutimes(usrtvp, ts)) != 0) 2120 return (error); 2121 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); 2122 if ((error = namei(&nd)) != 0) 2123 return (error); 2124 NDFREE(&nd, NDF_ONLY_PNBUF); 2125 error = setutimes(nd.ni_vp, ts, usrtvp == NULL); 2126 vrele(nd.ni_vp); 2127 return (error); 2128 } 2129 2130 /* 2131 * futimes_args(int fd, struct timeval *tptr) 2132 * 2133 * Set the access and modification times of a file. 2134 */ 2135 /* ARGSUSED */ 2136 int 2137 futimes(struct futimes_args *uap) 2138 { 2139 struct thread *td = curthread; 2140 struct proc *p = td->td_proc; 2141 struct timespec ts[2]; 2142 struct file *fp; 2143 struct timeval *usrtvp; 2144 int error; 2145 2146 usrtvp = SCARG(uap, tptr); 2147 if ((error = getutimes(usrtvp, ts)) != 0) 2148 return (error); 2149 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2150 return (error); 2151 return setutimes((struct vnode *)fp->f_data, ts, usrtvp == NULL); 2152 } 2153 2154 /* 2155 * truncate(char *path, int pad, off_t length) 2156 * 2157 * Truncate a file given its path name. 2158 */ 2159 /* ARGSUSED */ 2160 int 2161 truncate(struct truncate_args *uap) 2162 { 2163 struct thread *td = curthread; 2164 struct proc *p = td->td_proc; 2165 struct vnode *vp; 2166 struct vattr vattr; 2167 int error; 2168 struct nameidata nd; 2169 2170 if (uap->length < 0) 2171 return(EINVAL); 2172 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 2173 if ((error = namei(&nd)) != 0) 2174 return (error); 2175 vp = nd.ni_vp; 2176 NDFREE(&nd, NDF_ONLY_PNBUF); 2177 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2178 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2179 if (vp->v_type == VDIR) 2180 error = EISDIR; 2181 else if ((error = vn_writechk(vp)) == 0 && 2182 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, td)) == 0) { 2183 VATTR_NULL(&vattr); 2184 vattr.va_size = SCARG(uap, length); 2185 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 2186 } 2187 vput(vp); 2188 return (error); 2189 } 2190 2191 /* 2192 * ftruncate_args(int fd, int pad, off_t length) 2193 * 2194 * Truncate a file given a file descriptor. 2195 */ 2196 /* ARGSUSED */ 2197 int 2198 ftruncate(struct ftruncate_args *uap) 2199 { 2200 struct thread *td = curthread; 2201 struct proc *p = td->td_proc; 2202 struct vattr vattr; 2203 struct vnode *vp; 2204 struct file *fp; 2205 int error; 2206 2207 if (uap->length < 0) 2208 return(EINVAL); 2209 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2210 return (error); 2211 if ((fp->f_flag & FWRITE) == 0) 2212 return (EINVAL); 2213 vp = (struct vnode *)fp->f_data; 2214 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2215 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2216 if (vp->v_type == VDIR) 2217 error = EISDIR; 2218 else if ((error = vn_writechk(vp)) == 0) { 2219 VATTR_NULL(&vattr); 2220 vattr.va_size = SCARG(uap, length); 2221 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td); 2222 } 2223 VOP_UNLOCK(vp, 0, td); 2224 return (error); 2225 } 2226 2227 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 2228 /* 2229 * otruncate_args(char *path, long length) 2230 * 2231 * Truncate a file given its path name. 2232 */ 2233 /* ARGSUSED */ 2234 int 2235 otruncate(struct otruncate_args *uap) 2236 { 2237 struct truncate_args /* { 2238 syscallarg(char *) path; 2239 syscallarg(int) pad; 2240 syscallarg(off_t) length; 2241 } */ nuap; 2242 2243 SCARG(&nuap, path) = SCARG(uap, path); 2244 SCARG(&nuap, length) = SCARG(uap, length); 2245 return (truncate(&nuap)); 2246 } 2247 2248 /* 2249 * oftruncate_args(int fd, long length) 2250 * 2251 * Truncate a file given a file descriptor. 2252 */ 2253 /* ARGSUSED */ 2254 int 2255 oftruncate(struct oftruncate_args *uap) 2256 { 2257 struct ftruncate_args /* { 2258 syscallarg(int) fd; 2259 syscallarg(int) pad; 2260 syscallarg(off_t) length; 2261 } */ nuap; 2262 2263 SCARG(&nuap, fd) = SCARG(uap, fd); 2264 SCARG(&nuap, length) = SCARG(uap, length); 2265 return (ftruncate(&nuap)); 2266 } 2267 #endif /* COMPAT_43 || COMPAT_SUNOS */ 2268 2269 /* 2270 * fsync(int fd) 2271 * 2272 * Sync an open file. 2273 */ 2274 /* ARGSUSED */ 2275 int 2276 fsync(struct fsync_args *uap) 2277 { 2278 struct thread *td = curthread; 2279 struct proc *p = td->td_proc; 2280 struct vnode *vp; 2281 struct file *fp; 2282 vm_object_t obj; 2283 int error; 2284 2285 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2286 return (error); 2287 vp = (struct vnode *)fp->f_data; 2288 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2289 if (VOP_GETVOBJECT(vp, &obj) == 0) 2290 vm_object_page_clean(obj, 0, 0, 0); 2291 if ((error = VOP_FSYNC(vp, MNT_WAIT, td)) == 0 && 2292 vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && 2293 bioops.io_fsync) 2294 error = (*bioops.io_fsync)(vp); 2295 VOP_UNLOCK(vp, 0, td); 2296 return (error); 2297 } 2298 2299 /* 2300 * rename_args(char *from, char *to) 2301 * 2302 * Rename files. Source and destination must either both be directories, 2303 * or both not be directories. If target is a directory, it must be empty. 2304 */ 2305 /* ARGSUSED */ 2306 int 2307 rename(struct rename_args *uap) 2308 { 2309 struct thread *td = curthread; 2310 struct proc *p = td->td_proc; 2311 struct vnode *tvp, *fvp, *tdvp; 2312 struct nameidata fromnd, tond; 2313 int error; 2314 2315 bwillwrite(); 2316 NDINIT(&fromnd, NAMEI_DELETE, CNP_WANTPARENT | CNP_SAVESTART, 2317 UIO_USERSPACE, SCARG(uap, from), td); 2318 if ((error = namei(&fromnd)) != 0) 2319 return (error); 2320 fvp = fromnd.ni_vp; 2321 NDINIT(&tond, NAMEI_RENAME, 2322 CNP_LOCKPARENT | CNP_LOCKLEAF | CNP_NOCACHE | 2323 CNP_SAVESTART | CNP_NOOBJ, 2324 UIO_USERSPACE, SCARG(uap, to), td); 2325 if (fromnd.ni_vp->v_type == VDIR) 2326 tond.ni_cnd.cn_flags |= CNP_WILLBEDIR; 2327 if ((error = namei(&tond)) != 0) { 2328 /* Translate error code for rename("dir1", "dir2/."). */ 2329 if (error == EISDIR && fvp->v_type == VDIR) 2330 error = EINVAL; 2331 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2332 vrele(fromnd.ni_dvp); 2333 vrele(fvp); 2334 goto out1; 2335 } 2336 tdvp = tond.ni_dvp; 2337 tvp = tond.ni_vp; 2338 if (tvp != NULL) { 2339 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2340 error = ENOTDIR; 2341 goto out; 2342 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2343 error = EISDIR; 2344 goto out; 2345 } 2346 } 2347 if (fvp == tdvp) 2348 error = EINVAL; 2349 /* 2350 * If the source is the same as the destination (that is, if they 2351 * are links to the same vnode), then there is nothing to do. 2352 */ 2353 if (fvp == tvp) 2354 error = -1; 2355 out: 2356 if (!error) { 2357 VOP_LEASE(tdvp, td, p->p_ucred, LEASE_WRITE); 2358 if (fromnd.ni_dvp != tdvp) { 2359 VOP_LEASE(fromnd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 2360 } 2361 if (tvp) { 2362 VOP_LEASE(tvp, td, p->p_ucred, LEASE_WRITE); 2363 } 2364 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 2365 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 2366 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2367 NDFREE(&tond, NDF_ONLY_PNBUF); 2368 } else { 2369 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2370 NDFREE(&tond, NDF_ONLY_PNBUF); 2371 if (tdvp == tvp) 2372 vrele(tdvp); 2373 else 2374 vput(tdvp); 2375 if (tvp) 2376 vput(tvp); 2377 vrele(fromnd.ni_dvp); 2378 vrele(fvp); 2379 } 2380 vrele(tond.ni_startdir); 2381 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); 2382 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); 2383 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); 2384 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); 2385 out1: 2386 if (fromnd.ni_startdir) 2387 vrele(fromnd.ni_startdir); 2388 if (error == -1) 2389 return (0); 2390 return (error); 2391 } 2392 2393 /* 2394 * mkdir_args(char *path, int mode) 2395 * 2396 * Make a directory file. 2397 */ 2398 /* ARGSUSED */ 2399 int 2400 mkdir(struct mkdir_args *uap) 2401 { 2402 struct thread *td = curthread; 2403 struct proc *p = td->td_proc; 2404 struct vnode *vp; 2405 struct vattr vattr; 2406 int error; 2407 struct nameidata nd; 2408 2409 bwillwrite(); 2410 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, 2411 SCARG(uap, path), td); 2412 nd.ni_cnd.cn_flags |= CNP_WILLBEDIR; 2413 if ((error = namei(&nd)) != 0) 2414 return (error); 2415 vp = nd.ni_vp; 2416 if (vp != NULL) { 2417 NDFREE(&nd, NDF_ONLY_PNBUF); 2418 if (nd.ni_dvp == vp) 2419 vrele(nd.ni_dvp); 2420 else 2421 vput(nd.ni_dvp); 2422 vrele(vp); 2423 return (EEXIST); 2424 } 2425 VATTR_NULL(&vattr); 2426 vattr.va_type = VDIR; 2427 vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; 2428 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 2429 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 2430 NDFREE(&nd, NDF_ONLY_PNBUF); 2431 vput(nd.ni_dvp); 2432 if (!error) 2433 vput(nd.ni_vp); 2434 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); 2435 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); 2436 return (error); 2437 } 2438 2439 /* 2440 * rmdir_args(char *path) 2441 * 2442 * Remove a directory file. 2443 */ 2444 /* ARGSUSED */ 2445 int 2446 rmdir(struct rmdir_args *uap) 2447 { 2448 struct thread *td = curthread; 2449 struct proc *p = td->td_proc; 2450 struct vnode *vp; 2451 int error; 2452 struct nameidata nd; 2453 2454 bwillwrite(); 2455 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_LOCKLEAF, UIO_USERSPACE, 2456 SCARG(uap, path), td); 2457 if ((error = namei(&nd)) != 0) 2458 return (error); 2459 vp = nd.ni_vp; 2460 if (vp->v_type != VDIR) { 2461 error = ENOTDIR; 2462 goto out; 2463 } 2464 /* 2465 * No rmdir "." please. 2466 */ 2467 if (nd.ni_dvp == vp) { 2468 error = EINVAL; 2469 goto out; 2470 } 2471 /* 2472 * The root of a mounted filesystem cannot be deleted. 2473 */ 2474 if (vp->v_flag & VROOT) 2475 error = EBUSY; 2476 else { 2477 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); 2478 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2479 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 2480 } 2481 out: 2482 NDFREE(&nd, NDF_ONLY_PNBUF); 2483 if (nd.ni_dvp == vp) 2484 vrele(nd.ni_dvp); 2485 else 2486 vput(nd.ni_dvp); 2487 if (vp != NULLVP) 2488 vput(vp); 2489 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); 2490 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); 2491 return (error); 2492 } 2493 2494 #ifdef COMPAT_43 2495 /* 2496 * ogetdirentries_args(int fd, char *buf, u_int count, long *basep) 2497 * 2498 * Read a block of directory entries in a file system independent format. 2499 */ 2500 int 2501 ogetdirentries(struct ogetdirentries_args *uap) 2502 { 2503 struct thread *td = curthread; 2504 struct proc *p = td->td_proc; 2505 struct vnode *vp; 2506 struct file *fp; 2507 struct uio auio, kuio; 2508 struct iovec aiov, kiov; 2509 struct dirent *dp, *edp; 2510 caddr_t dirbuf; 2511 int error, eofflag, readcnt; 2512 long loff; 2513 2514 /* XXX arbitrary sanity limit on `count'. */ 2515 if (SCARG(uap, count) > 64 * 1024) 2516 return (EINVAL); 2517 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2518 return (error); 2519 if ((fp->f_flag & FREAD) == 0) 2520 return (EBADF); 2521 vp = (struct vnode *)fp->f_data; 2522 unionread: 2523 if (vp->v_type != VDIR) 2524 return (EINVAL); 2525 aiov.iov_base = SCARG(uap, buf); 2526 aiov.iov_len = SCARG(uap, count); 2527 auio.uio_iov = &aiov; 2528 auio.uio_iovcnt = 1; 2529 auio.uio_rw = UIO_READ; 2530 auio.uio_segflg = UIO_USERSPACE; 2531 auio.uio_td = td; 2532 auio.uio_resid = SCARG(uap, count); 2533 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2534 loff = auio.uio_offset = fp->f_offset; 2535 # if (BYTE_ORDER != LITTLE_ENDIAN) 2536 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 2537 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 2538 NULL, NULL); 2539 fp->f_offset = auio.uio_offset; 2540 } else 2541 # endif 2542 { 2543 kuio = auio; 2544 kuio.uio_iov = &kiov; 2545 kuio.uio_segflg = UIO_SYSSPACE; 2546 kiov.iov_len = SCARG(uap, count); 2547 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK); 2548 kiov.iov_base = dirbuf; 2549 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 2550 NULL, NULL); 2551 fp->f_offset = kuio.uio_offset; 2552 if (error == 0) { 2553 readcnt = SCARG(uap, count) - kuio.uio_resid; 2554 edp = (struct dirent *)&dirbuf[readcnt]; 2555 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 2556 # if (BYTE_ORDER == LITTLE_ENDIAN) 2557 /* 2558 * The expected low byte of 2559 * dp->d_namlen is our dp->d_type. 2560 * The high MBZ byte of dp->d_namlen 2561 * is our dp->d_namlen. 2562 */ 2563 dp->d_type = dp->d_namlen; 2564 dp->d_namlen = 0; 2565 # else 2566 /* 2567 * The dp->d_type is the high byte 2568 * of the expected dp->d_namlen, 2569 * so must be zero'ed. 2570 */ 2571 dp->d_type = 0; 2572 # endif 2573 if (dp->d_reclen > 0) { 2574 dp = (struct dirent *) 2575 ((char *)dp + dp->d_reclen); 2576 } else { 2577 error = EIO; 2578 break; 2579 } 2580 } 2581 if (dp >= edp) 2582 error = uiomove(dirbuf, readcnt, &auio); 2583 } 2584 FREE(dirbuf, M_TEMP); 2585 } 2586 VOP_UNLOCK(vp, 0, td); 2587 if (error) 2588 return (error); 2589 if (SCARG(uap, count) == auio.uio_resid) { 2590 if (union_dircheckp) { 2591 error = union_dircheckp(td, &vp, fp); 2592 if (error == -1) 2593 goto unionread; 2594 if (error) 2595 return (error); 2596 } 2597 if ((vp->v_flag & VROOT) && 2598 (vp->v_mount->mnt_flag & MNT_UNION)) { 2599 struct vnode *tvp = vp; 2600 vp = vp->v_mount->mnt_vnodecovered; 2601 VREF(vp); 2602 fp->f_data = (caddr_t) vp; 2603 fp->f_offset = 0; 2604 vrele(tvp); 2605 goto unionread; 2606 } 2607 } 2608 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2609 sizeof(long)); 2610 uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; 2611 return (error); 2612 } 2613 #endif /* COMPAT_43 */ 2614 2615 /* 2616 * getdirentries_args(int fd, char *buf, u_int conut, long *basep) 2617 * 2618 * Read a block of directory entries in a file system independent format. 2619 */ 2620 int 2621 getdirentries(struct getdirentries_args *uap) 2622 { 2623 struct thread *td = curthread; 2624 struct proc *p = td->td_proc; 2625 struct vnode *vp; 2626 struct file *fp; 2627 struct uio auio; 2628 struct iovec aiov; 2629 long loff; 2630 int error, eofflag; 2631 2632 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2633 return (error); 2634 if ((fp->f_flag & FREAD) == 0) 2635 return (EBADF); 2636 vp = (struct vnode *)fp->f_data; 2637 unionread: 2638 if (vp->v_type != VDIR) 2639 return (EINVAL); 2640 aiov.iov_base = SCARG(uap, buf); 2641 aiov.iov_len = SCARG(uap, count); 2642 auio.uio_iov = &aiov; 2643 auio.uio_iovcnt = 1; 2644 auio.uio_rw = UIO_READ; 2645 auio.uio_segflg = UIO_USERSPACE; 2646 auio.uio_td = td; 2647 auio.uio_resid = SCARG(uap, count); 2648 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */ 2649 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2650 loff = auio.uio_offset = fp->f_offset; 2651 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 2652 fp->f_offset = auio.uio_offset; 2653 VOP_UNLOCK(vp, 0, td); 2654 if (error) 2655 return (error); 2656 if (SCARG(uap, count) == auio.uio_resid) { 2657 if (union_dircheckp) { 2658 error = union_dircheckp(td, &vp, fp); 2659 if (error == -1) 2660 goto unionread; 2661 if (error) 2662 return (error); 2663 } 2664 if ((vp->v_flag & VROOT) && 2665 (vp->v_mount->mnt_flag & MNT_UNION)) { 2666 struct vnode *tvp = vp; 2667 vp = vp->v_mount->mnt_vnodecovered; 2668 VREF(vp); 2669 fp->f_data = (caddr_t) vp; 2670 fp->f_offset = 0; 2671 vrele(tvp); 2672 goto unionread; 2673 } 2674 } 2675 if (SCARG(uap, basep) != NULL) { 2676 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2677 sizeof(long)); 2678 } 2679 uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; 2680 return (error); 2681 } 2682 2683 /* 2684 * getdents_args(int fd, char *buf, size_t count) 2685 */ 2686 int 2687 getdents(struct getdents_args *uap) 2688 { 2689 struct getdirentries_args ap; 2690 2691 ap.fd = uap->fd; 2692 ap.buf = uap->buf; 2693 ap.count = uap->count; 2694 ap.basep = NULL; 2695 return getdirentries(&ap); 2696 } 2697 2698 /* 2699 * umask(int newmask) 2700 * 2701 * Set the mode mask for creation of filesystem nodes. 2702 * 2703 * MP SAFE 2704 */ 2705 int 2706 umask(struct umask_args *uap) 2707 { 2708 struct thread *td = curthread; 2709 struct proc *p = td->td_proc; 2710 struct filedesc *fdp; 2711 2712 fdp = p->p_fd; 2713 uap->sysmsg_result = fdp->fd_cmask; 2714 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; 2715 return (0); 2716 } 2717 2718 /* 2719 * revoke(char *path) 2720 * 2721 * Void all references to file by ripping underlying filesystem 2722 * away from vnode. 2723 */ 2724 /* ARGSUSED */ 2725 int 2726 revoke(struct revoke_args *uap) 2727 { 2728 struct thread *td = curthread; 2729 struct proc *p = td->td_proc; 2730 struct vnode *vp; 2731 struct vattr vattr; 2732 int error; 2733 struct nameidata nd; 2734 2735 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 2736 if ((error = namei(&nd)) != 0) 2737 return (error); 2738 vp = nd.ni_vp; 2739 NDFREE(&nd, NDF_ONLY_PNBUF); 2740 if (vp->v_type != VCHR && vp->v_type != VBLK) { 2741 error = EINVAL; 2742 goto out; 2743 } 2744 if ((error = VOP_GETATTR(vp, &vattr, td)) != 0) 2745 goto out; 2746 if (p->p_ucred->cr_uid != vattr.va_uid && 2747 (error = suser_cred(p->p_ucred, PRISON_ROOT))) 2748 goto out; 2749 if (vcount(vp) > 1) 2750 VOP_REVOKE(vp, REVOKEALL); 2751 out: 2752 vrele(vp); 2753 return (error); 2754 } 2755 2756 /* 2757 * Convert a user file descriptor to a kernel file entry. 2758 */ 2759 int 2760 getvnode(struct filedesc *fdp, int fd, struct file **fpp) 2761 { 2762 struct file *fp; 2763 2764 if ((u_int)fd >= fdp->fd_nfiles || 2765 (fp = fdp->fd_ofiles[fd]) == NULL) 2766 return (EBADF); 2767 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) 2768 return (EINVAL); 2769 *fpp = fp; 2770 return (0); 2771 } 2772 /* 2773 * getfh_args(char *fname, fhandle_t *fhp) 2774 * 2775 * Get (NFS) file handle 2776 */ 2777 int 2778 getfh(struct getfh_args *uap) 2779 { 2780 struct thread *td = curthread; 2781 struct nameidata nd; 2782 fhandle_t fh; 2783 struct vnode *vp; 2784 int error; 2785 2786 /* 2787 * Must be super user 2788 */ 2789 error = suser(td); 2790 if (error) 2791 return (error); 2792 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, uap->fname, td); 2793 error = namei(&nd); 2794 if (error) 2795 return (error); 2796 NDFREE(&nd, NDF_ONLY_PNBUF); 2797 vp = nd.ni_vp; 2798 bzero(&fh, sizeof(fh)); 2799 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 2800 error = VFS_VPTOFH(vp, &fh.fh_fid); 2801 vput(vp); 2802 if (error) 2803 return (error); 2804 error = copyout(&fh, uap->fhp, sizeof (fh)); 2805 return (error); 2806 } 2807 2808 /* 2809 * fhopen_args(const struct fhandle *u_fhp, int flags) 2810 * 2811 * syscall for the rpc.lockd to use to translate a NFS file handle into 2812 * an open descriptor. 2813 * 2814 * warning: do not remove the suser() call or this becomes one giant 2815 * security hole. 2816 */ 2817 int 2818 fhopen(struct fhopen_args *uap) 2819 { 2820 struct thread *td = curthread; 2821 struct proc *p = td->td_proc; 2822 struct mount *mp; 2823 struct vnode *vp; 2824 struct fhandle fhp; 2825 struct vattr vat; 2826 struct vattr *vap = &vat; 2827 struct flock lf; 2828 struct file *fp; 2829 struct filedesc *fdp = p->p_fd; 2830 int fmode, mode, error, type; 2831 struct file *nfp; 2832 int indx; 2833 2834 /* 2835 * Must be super user 2836 */ 2837 error = suser(td); 2838 if (error) 2839 return (error); 2840 2841 fmode = FFLAGS(SCARG(uap, flags)); 2842 /* why not allow a non-read/write open for our lockd? */ 2843 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 2844 return (EINVAL); 2845 error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp)); 2846 if (error) 2847 return(error); 2848 /* find the mount point */ 2849 mp = vfs_getvfs(&fhp.fh_fsid); 2850 if (mp == NULL) 2851 return (ESTALE); 2852 /* now give me my vnode, it gets returned to me locked */ 2853 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 2854 if (error) 2855 return (error); 2856 /* 2857 * from now on we have to make sure not 2858 * to forget about the vnode 2859 * any error that causes an abort must vput(vp) 2860 * just set error = err and 'goto bad;'. 2861 */ 2862 2863 /* 2864 * from vn_open 2865 */ 2866 if (vp->v_type == VLNK) { 2867 error = EMLINK; 2868 goto bad; 2869 } 2870 if (vp->v_type == VSOCK) { 2871 error = EOPNOTSUPP; 2872 goto bad; 2873 } 2874 mode = 0; 2875 if (fmode & (FWRITE | O_TRUNC)) { 2876 if (vp->v_type == VDIR) { 2877 error = EISDIR; 2878 goto bad; 2879 } 2880 error = vn_writechk(vp); 2881 if (error) 2882 goto bad; 2883 mode |= VWRITE; 2884 } 2885 if (fmode & FREAD) 2886 mode |= VREAD; 2887 if (mode) { 2888 error = VOP_ACCESS(vp, mode, p->p_ucred, td); 2889 if (error) 2890 goto bad; 2891 } 2892 if (fmode & O_TRUNC) { 2893 VOP_UNLOCK(vp, 0, td); /* XXX */ 2894 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2895 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */ 2896 VATTR_NULL(vap); 2897 vap->va_size = 0; 2898 error = VOP_SETATTR(vp, vap, p->p_ucred, td); 2899 if (error) 2900 goto bad; 2901 } 2902 error = VOP_OPEN(vp, fmode, p->p_ucred, td); 2903 if (error) 2904 goto bad; 2905 /* 2906 * Make sure that a VM object is created for VMIO support. 2907 */ 2908 if (vn_canvmio(vp) == TRUE) { 2909 if ((error = vfs_object_create(vp, td)) != 0) 2910 goto bad; 2911 } 2912 if (fmode & FWRITE) 2913 vp->v_writecount++; 2914 2915 /* 2916 * end of vn_open code 2917 */ 2918 2919 if ((error = falloc(p, &nfp, &indx)) != 0) { 2920 if (fmode & FWRITE) 2921 vp->v_writecount--; 2922 goto bad; 2923 } 2924 fp = nfp; 2925 2926 /* 2927 * hold an extra reference to avoid having fp ripped out 2928 * from under us while we block in the lock op. 2929 */ 2930 fhold(fp); 2931 nfp->f_data = (caddr_t)vp; 2932 nfp->f_flag = fmode & FMASK; 2933 nfp->f_ops = &vnops; 2934 nfp->f_type = DTYPE_VNODE; 2935 if (fmode & (O_EXLOCK | O_SHLOCK)) { 2936 lf.l_whence = SEEK_SET; 2937 lf.l_start = 0; 2938 lf.l_len = 0; 2939 if (fmode & O_EXLOCK) 2940 lf.l_type = F_WRLCK; 2941 else 2942 lf.l_type = F_RDLCK; 2943 type = F_FLOCK; 2944 if ((fmode & FNONBLOCK) == 0) 2945 type |= F_WAIT; 2946 VOP_UNLOCK(vp, 0, td); 2947 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 2948 /* 2949 * lock request failed. Normally close the descriptor 2950 * but handle the case where someone might have dup()d 2951 * or close()d it when we weren't looking. 2952 */ 2953 if (fdp->fd_ofiles[indx] == fp) { 2954 fdp->fd_ofiles[indx] = NULL; 2955 fdrop(fp, td); 2956 } 2957 2958 /* 2959 * release our private reference. 2960 */ 2961 fdrop(fp, td); 2962 return (error); 2963 } 2964 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2965 fp->f_flag |= FHASLOCK; 2966 } 2967 if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0)) 2968 vfs_object_create(vp, td); 2969 2970 VOP_UNLOCK(vp, 0, td); 2971 fdrop(fp, td); 2972 uap->sysmsg_result = indx; 2973 return (0); 2974 2975 bad: 2976 vput(vp); 2977 return (error); 2978 } 2979 2980 /* 2981 * fhstat_args(struct fhandle *u_fhp, struct stat *sb) 2982 */ 2983 int 2984 fhstat(struct fhstat_args *uap) 2985 { 2986 struct thread *td = curthread; 2987 struct stat sb; 2988 fhandle_t fh; 2989 struct mount *mp; 2990 struct vnode *vp; 2991 int error; 2992 2993 /* 2994 * Must be super user 2995 */ 2996 error = suser(td); 2997 if (error) 2998 return (error); 2999 3000 error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t)); 3001 if (error) 3002 return (error); 3003 3004 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3005 return (ESTALE); 3006 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3007 return (error); 3008 error = vn_stat(vp, &sb, td); 3009 vput(vp); 3010 if (error) 3011 return (error); 3012 error = copyout(&sb, SCARG(uap, sb), sizeof(sb)); 3013 return (error); 3014 } 3015 3016 /* 3017 * fhstatfs_args(struct fhandle *u_fhp, struct statfs *buf) 3018 */ 3019 int 3020 fhstatfs(struct fhstatfs_args *uap) 3021 { 3022 struct thread *td = curthread; 3023 struct statfs *sp; 3024 struct mount *mp; 3025 struct vnode *vp; 3026 struct statfs sb; 3027 fhandle_t fh; 3028 int error; 3029 3030 /* 3031 * Must be super user 3032 */ 3033 if ((error = suser(td))) 3034 return (error); 3035 3036 if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0) 3037 return (error); 3038 3039 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3040 return (ESTALE); 3041 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3042 return (error); 3043 mp = vp->v_mount; 3044 sp = &mp->mnt_stat; 3045 vput(vp); 3046 if ((error = VFS_STATFS(mp, sp, td)) != 0) 3047 return (error); 3048 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 3049 if (suser(td)) { 3050 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 3051 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 3052 sp = &sb; 3053 } 3054 return (copyout(sp, SCARG(uap, buf), sizeof(*sp))); 3055 } 3056 3057 /* 3058 * Syscall to push extended attribute configuration information into the 3059 * VFS. Accepts a path, which it converts to a mountpoint, as well as 3060 * a command (int cmd), and attribute name and misc data. For now, the 3061 * attribute name is left in userspace for consumption by the VFS_op. 3062 * It will probably be changed to be copied into sysspace by the 3063 * syscall in the future, once issues with various consumers of the 3064 * attribute code have raised their hands. 3065 * 3066 * Currently this is used only by UFS Extended Attributes. 3067 */ 3068 int 3069 extattrctl(struct extattrctl_args *uap) 3070 { 3071 struct thread *td = curthread; 3072 struct nameidata nd; 3073 struct mount *mp; 3074 int error; 3075 3076 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 3077 if ((error = namei(&nd)) != 0) 3078 return (error); 3079 mp = nd.ni_vp->v_mount; 3080 NDFREE(&nd, 0); 3081 return (VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname), 3082 SCARG(uap, arg), td)); 3083 } 3084 3085 /* 3086 * Syscall to set a named extended attribute on a file or directory. 3087 * Accepts attribute name, and a uio structure pointing to the data to set. 3088 * The uio is consumed in the style of writev(). The real work happens 3089 * in VOP_SETEXTATTR(). 3090 */ 3091 int 3092 extattr_set_file(struct extattr_set_file_args *uap) 3093 { 3094 struct thread *td = curthread; 3095 struct proc *p = td->td_proc; 3096 struct nameidata nd; 3097 struct uio auio; 3098 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 3099 char attrname[EXTATTR_MAXNAMELEN]; 3100 u_int iovlen, cnt; 3101 int error, i; 3102 3103 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3104 if (error) 3105 return (error); 3106 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3107 SCARG(uap, path), td); 3108 if ((error = namei(&nd)) != 0) 3109 return(error); 3110 iovlen = uap->iovcnt * sizeof(struct iovec); 3111 if (uap->iovcnt > UIO_SMALLIOV) { 3112 if (uap->iovcnt > UIO_MAXIOV) { 3113 error = EINVAL; 3114 goto done; 3115 } 3116 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3117 needfree = iov; 3118 } else 3119 iov = aiov; 3120 auio.uio_iov = iov; 3121 auio.uio_iovcnt = uap->iovcnt; 3122 auio.uio_rw = UIO_WRITE; 3123 auio.uio_segflg = UIO_USERSPACE; 3124 auio.uio_td = td; 3125 auio.uio_offset = 0; 3126 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3127 goto done; 3128 auio.uio_resid = 0; 3129 for (i = 0; i < uap->iovcnt; i++) { 3130 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3131 error = EINVAL; 3132 goto done; 3133 } 3134 auio.uio_resid += iov->iov_len; 3135 iov++; 3136 } 3137 cnt = auio.uio_resid; 3138 error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td); 3139 cnt -= auio.uio_resid; 3140 uap->sysmsg_result = cnt; 3141 done: 3142 if (needfree) 3143 FREE(needfree, M_IOV); 3144 NDFREE(&nd, 0); 3145 return (error); 3146 } 3147 3148 /* 3149 * Syscall to get a named extended attribute on a file or directory. 3150 * Accepts attribute name, and a uio structure pointing to a buffer for the 3151 * data. The uio is consumed in the style of readv(). The real work 3152 * happens in VOP_GETEXTATTR(); 3153 */ 3154 int 3155 extattr_get_file(struct extattr_get_file_args *uap) 3156 { 3157 struct thread *td = curthread; 3158 struct proc *p = td->td_proc; 3159 struct nameidata nd; 3160 struct uio auio; 3161 struct iovec *iov, *needfree, aiov[UIO_SMALLIOV]; 3162 char attrname[EXTATTR_MAXNAMELEN]; 3163 u_int iovlen, cnt; 3164 int error, i; 3165 3166 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3167 if (error) 3168 return (error); 3169 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3170 SCARG(uap, path), td); 3171 if ((error = namei(&nd)) != 0) 3172 return (error); 3173 iovlen = uap->iovcnt * sizeof (struct iovec); 3174 if (uap->iovcnt > UIO_SMALLIOV) { 3175 if (uap->iovcnt > UIO_MAXIOV) { 3176 NDFREE(&nd, 0); 3177 return (EINVAL); 3178 } 3179 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3180 needfree = iov; 3181 } else { 3182 iov = aiov; 3183 needfree = NULL; 3184 } 3185 auio.uio_iov = iov; 3186 auio.uio_iovcnt = uap->iovcnt; 3187 auio.uio_rw = UIO_READ; 3188 auio.uio_segflg = UIO_USERSPACE; 3189 auio.uio_td = td; 3190 auio.uio_offset = 0; 3191 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3192 goto done; 3193 auio.uio_resid = 0; 3194 for (i = 0; i < uap->iovcnt; i++) { 3195 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3196 error = EINVAL; 3197 goto done; 3198 } 3199 auio.uio_resid += iov->iov_len; 3200 iov++; 3201 } 3202 cnt = auio.uio_resid; 3203 error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td); 3204 cnt -= auio.uio_resid; 3205 uap->sysmsg_result = cnt; 3206 done: 3207 if (needfree) 3208 FREE(needfree, M_IOV); 3209 NDFREE(&nd, 0); 3210 return(error); 3211 } 3212 3213 /* 3214 * Syscall to delete a named extended attribute from a file or directory. 3215 * Accepts attribute name. The real work happens in VOP_SETEXTATTR(). 3216 */ 3217 int 3218 extattr_delete_file(struct extattr_delete_file_args *uap) 3219 { 3220 struct thread *td = curthread; 3221 struct proc *p = td->td_proc; 3222 struct nameidata nd; 3223 char attrname[EXTATTR_MAXNAMELEN]; 3224 int error; 3225 3226 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3227 if (error) 3228 return(error); 3229 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3230 SCARG(uap, path), td); 3231 if ((error = namei(&nd)) != 0) 3232 return(error); 3233 error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_ucred, td); 3234 NDFREE(&nd, 0); 3235 return(error); 3236 } 3237