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