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.26 2003/11/12 10:11:09 daver 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, off_t *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_offset); 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 /* 1731 * XXX: daver 1732 * kern_readlink isn't properly split yet. There is a copyin burried 1733 * in VOP_READLINK(). 1734 */ 1735 int 1736 kern_readlink(struct nameidata *nd, char *buf, int count, int *res) 1737 { 1738 struct thread *td = curthread; 1739 struct proc *p = td->td_proc; 1740 struct vnode *vp; 1741 struct iovec aiov; 1742 struct uio auio; 1743 int error; 1744 1745 error = namei(nd); 1746 if (error) 1747 return (error); 1748 NDFREE(nd, NDF_ONLY_PNBUF); 1749 vp = nd->ni_vp; 1750 if (vp->v_type != VLNK) 1751 error = EINVAL; 1752 else { 1753 aiov.iov_base = buf; 1754 aiov.iov_len = count; 1755 auio.uio_iov = &aiov; 1756 auio.uio_iovcnt = 1; 1757 auio.uio_offset = 0; 1758 auio.uio_rw = UIO_READ; 1759 auio.uio_segflg = UIO_USERSPACE; 1760 auio.uio_td = td; 1761 auio.uio_resid = count; 1762 error = VOP_READLINK(vp, &auio, p->p_ucred); 1763 } 1764 vput(vp); 1765 *res = count - auio.uio_resid; 1766 return (error); 1767 } 1768 1769 /* 1770 * readlink_args(char *path, char *buf, int count) 1771 * 1772 * Return target name of a symbolic link. 1773 */ 1774 int 1775 readlink(struct readlink_args *uap) 1776 { 1777 struct thread *td = curthread; 1778 struct nameidata nd; 1779 int error; 1780 1781 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, UIO_USERSPACE, 1782 uap->path, td); 1783 1784 error = kern_readlink(&nd, uap->buf, uap->count, 1785 &uap->sysmsg_result); 1786 1787 return (error); 1788 } 1789 1790 static int 1791 setfflags(struct vnode *vp, int flags) 1792 { 1793 struct thread *td = curthread; 1794 struct proc *p = td->td_proc; 1795 int error; 1796 struct vattr vattr; 1797 1798 /* 1799 * Prevent non-root users from setting flags on devices. When 1800 * a device is reused, users can retain ownership of the device 1801 * if they are allowed to set flags and programs assume that 1802 * chown can't fail when done as root. 1803 */ 1804 if ((vp->v_type == VCHR || vp->v_type == VBLK) && 1805 ((error = suser_cred(p->p_ucred, PRISON_ROOT)) != 0)) 1806 return (error); 1807 1808 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1809 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1810 VATTR_NULL(&vattr); 1811 vattr.va_flags = flags; 1812 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1813 VOP_UNLOCK(vp, 0, td); 1814 return (error); 1815 } 1816 1817 /* 1818 * chflags(char *path, int flags) 1819 * 1820 * Change flags of a file given a path name. 1821 */ 1822 /* ARGSUSED */ 1823 int 1824 chflags(struct chflags_args *uap) 1825 { 1826 struct thread *td = curthread; 1827 int error; 1828 struct nameidata nd; 1829 1830 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, 1831 SCARG(uap, path), td); 1832 if ((error = namei(&nd)) != 0) 1833 return (error); 1834 NDFREE(&nd, NDF_ONLY_PNBUF); 1835 error = setfflags(nd.ni_vp, SCARG(uap, flags)); 1836 vrele(nd.ni_vp); 1837 return error; 1838 } 1839 1840 /* 1841 * fchflags_args(int fd, int flags) 1842 * 1843 * Change flags of a file given a file descriptor. 1844 */ 1845 /* ARGSUSED */ 1846 int 1847 fchflags(struct fchflags_args *uap) 1848 { 1849 struct thread *td = curthread; 1850 struct proc *p = td->td_proc; 1851 struct file *fp; 1852 int error; 1853 1854 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1855 return (error); 1856 return setfflags((struct vnode *) fp->f_data, SCARG(uap, flags)); 1857 } 1858 1859 static int 1860 setfmode(struct vnode *vp, int mode) 1861 { 1862 struct thread *td = curthread; 1863 struct proc *p = td->td_proc; 1864 int error; 1865 struct vattr vattr; 1866 1867 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1868 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1869 VATTR_NULL(&vattr); 1870 vattr.va_mode = mode & ALLPERMS; 1871 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1872 VOP_UNLOCK(vp, 0, td); 1873 return error; 1874 } 1875 1876 int 1877 kern_chmod(struct nameidata *nd, int mode) 1878 { 1879 int error; 1880 1881 error = namei(nd); 1882 if (error) 1883 return (error); 1884 NDFREE(nd, NDF_ONLY_PNBUF); 1885 error = setfmode(nd->ni_vp, mode); 1886 vrele(nd->ni_vp); 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 struct nameidata nd; 1901 int error; 1902 1903 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); 1904 1905 error = kern_chmod(&nd, uap->mode); 1906 1907 return (error); 1908 } 1909 1910 /* 1911 * lchmod_args(char *path, int mode) 1912 * 1913 * Change mode of a file given path name (don't follow links.) 1914 */ 1915 /* ARGSUSED */ 1916 int 1917 lchmod(struct lchmod_args *uap) 1918 { 1919 struct thread *td = curthread; 1920 int error; 1921 struct nameidata nd; 1922 1923 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); 1924 if ((error = namei(&nd)) != 0) 1925 return (error); 1926 NDFREE(&nd, NDF_ONLY_PNBUF); 1927 error = setfmode(nd.ni_vp, SCARG(uap, mode)); 1928 vrele(nd.ni_vp); 1929 return error; 1930 } 1931 1932 /* 1933 * fchmod_args(int fd, int mode) 1934 * 1935 * Change mode of a file given a file descriptor. 1936 */ 1937 /* ARGSUSED */ 1938 int 1939 fchmod(struct fchmod_args *uap) 1940 { 1941 struct thread *td = curthread; 1942 struct proc *p = td->td_proc; 1943 struct file *fp; 1944 int error; 1945 1946 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1947 return (error); 1948 return setfmode((struct vnode *)fp->f_data, SCARG(uap, mode)); 1949 } 1950 1951 static int 1952 setfown(struct vnode *vp, uid_t uid, gid_t gid) 1953 { 1954 struct thread *td = curthread; 1955 struct proc *p = td->td_proc; 1956 int error; 1957 struct vattr vattr; 1958 1959 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 1960 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1961 VATTR_NULL(&vattr); 1962 vattr.va_uid = uid; 1963 vattr.va_gid = gid; 1964 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 1965 VOP_UNLOCK(vp, 0, td); 1966 return error; 1967 } 1968 1969 int 1970 kern_chown(struct nameidata *nd, int uid, int gid) 1971 { 1972 int error; 1973 1974 error = namei(nd); 1975 if (error) 1976 return (error); 1977 NDFREE(nd, NDF_ONLY_PNBUF); 1978 error = setfown(nd->ni_vp, uid, gid); 1979 vrele(nd->ni_vp); 1980 return (error); 1981 } 1982 1983 /* 1984 * chown(char *path, int uid, int gid) 1985 * 1986 * Set ownership given a path name. 1987 */ 1988 int 1989 chown(struct chown_args *uap) 1990 { 1991 struct thread *td = curthread; 1992 struct nameidata nd; 1993 int error; 1994 1995 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); 1996 1997 error = kern_chown(&nd, uap->uid, uap->gid); 1998 1999 return (error); 2000 } 2001 2002 /* 2003 * lchown_args(char *path, int uid, int gid) 2004 * 2005 * Set ownership given a path name, do not cross symlinks. 2006 */ 2007 int 2008 lchown(struct lchown_args *uap) 2009 { 2010 struct thread *td = curthread; 2011 int error; 2012 struct nameidata nd; 2013 2014 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, uap->path, td); 2015 2016 error = kern_chown(&nd, uap->uid, uap->gid); 2017 2018 return (error); 2019 } 2020 2021 /* 2022 * fchown_args(int fd, int uid, int gid) 2023 * 2024 * Set ownership given a file descriptor. 2025 */ 2026 /* ARGSUSED */ 2027 int 2028 fchown(struct fchown_args *uap) 2029 { 2030 struct thread *td = curthread; 2031 struct proc *p = td->td_proc; 2032 struct file *fp; 2033 int error; 2034 2035 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2036 return (error); 2037 return setfown((struct vnode *)fp->f_data, 2038 SCARG(uap, uid), SCARG(uap, gid)); 2039 } 2040 2041 static int 2042 getutimes(const struct timeval *tvp, struct timespec *tsp) 2043 { 2044 struct timeval tv[2]; 2045 2046 if (tvp == NULL) { 2047 microtime(&tv[0]); 2048 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2049 tsp[1] = tsp[0]; 2050 } else { 2051 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 2052 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 2053 } 2054 return 0; 2055 } 2056 2057 static int 2058 setutimes(struct vnode *vp, const struct timespec *ts, int nullflag) 2059 { 2060 struct thread *td = curthread; 2061 struct proc *p = td->td_proc; 2062 int error; 2063 struct vattr vattr; 2064 2065 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2066 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2067 VATTR_NULL(&vattr); 2068 vattr.va_atime = ts[0]; 2069 vattr.va_mtime = ts[1]; 2070 if (nullflag) 2071 vattr.va_vaflags |= VA_UTIMES_NULL; 2072 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 2073 VOP_UNLOCK(vp, 0, td); 2074 return error; 2075 } 2076 2077 int 2078 kern_utimes(struct nameidata *nd, struct timeval *tptr) 2079 { 2080 struct timespec ts[2]; 2081 int error; 2082 2083 error = getutimes(tptr, ts); 2084 if (error) 2085 return (error); 2086 error = namei(nd); 2087 if (error) 2088 return (error); 2089 NDFREE(nd, NDF_ONLY_PNBUF); 2090 error = setutimes(nd->ni_vp, ts, tptr == NULL); 2091 vrele(nd->ni_vp); 2092 return (error); 2093 } 2094 2095 /* 2096 * utimes_args(char *path, struct timeval *tptr) 2097 * 2098 * Set the access and modification times of a file. 2099 */ 2100 int 2101 utimes(struct utimes_args *uap) 2102 { 2103 struct thread *td = curthread; 2104 struct timeval tv[2]; 2105 struct nameidata nd; 2106 int error; 2107 2108 if (uap->tptr) { 2109 error = copyin(uap->tptr, tv, sizeof(tv)); 2110 if (error) 2111 return (error); 2112 } 2113 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); 2114 2115 error = kern_utimes(&nd, uap->tptr ? tv : NULL); 2116 2117 return (error); 2118 } 2119 2120 /* 2121 * lutimes_args(char *path, struct timeval *tptr) 2122 * 2123 * Set the access and modification times of a file. 2124 */ 2125 int 2126 lutimes(struct lutimes_args *uap) 2127 { 2128 struct thread *td = curthread; 2129 struct timeval tv[2]; 2130 struct nameidata nd; 2131 int error; 2132 2133 if (uap->tptr) { 2134 error = copyin(uap->tptr, tv, sizeof(tv)); 2135 if (error) 2136 return (error); 2137 } 2138 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, uap->path, td); 2139 2140 error = kern_utimes(&nd, uap->tptr ? tv : NULL); 2141 2142 return (error); 2143 } 2144 2145 int 2146 kern_futimes(int fd, struct timeval *tptr) 2147 { 2148 struct thread *td = curthread; 2149 struct proc *p = td->td_proc; 2150 struct timespec ts[2]; 2151 struct file *fp; 2152 int error; 2153 2154 error = getutimes(tptr, ts); 2155 if (error) 2156 return (error); 2157 error = getvnode(p->p_fd, fd, &fp); 2158 if (error) 2159 return (error); 2160 error = setutimes((struct vnode *)fp->f_data, ts, tptr == NULL); 2161 return (error); 2162 } 2163 2164 /* 2165 * futimes_args(int fd, struct timeval *tptr) 2166 * 2167 * Set the access and modification times of a file. 2168 */ 2169 int 2170 futimes(struct futimes_args *uap) 2171 { 2172 struct timeval tv[2]; 2173 int error; 2174 2175 if (uap->tptr) { 2176 error = copyin(uap->tptr, tv, sizeof(tv)); 2177 if (error) 2178 return (error); 2179 } 2180 2181 error = kern_futimes(uap->fd, uap->tptr ? tv : NULL); 2182 2183 return (error); 2184 } 2185 2186 int 2187 kern_truncate(struct nameidata* nd, off_t length) 2188 { 2189 struct thread *td = curthread; 2190 struct proc *p = td->td_proc; 2191 struct vnode *vp; 2192 struct vattr vattr; 2193 int error; 2194 2195 if (length < 0) 2196 return(EINVAL); 2197 if ((error = namei(nd)) != 0) 2198 return (error); 2199 vp = nd->ni_vp; 2200 NDFREE(nd, NDF_ONLY_PNBUF); 2201 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2202 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2203 if (vp->v_type == VDIR) 2204 error = EISDIR; 2205 else if ((error = vn_writechk(vp)) == 0 && 2206 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, td)) == 0) { 2207 VATTR_NULL(&vattr); 2208 vattr.va_size = length; 2209 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); 2210 } 2211 vput(vp); 2212 return (error); 2213 } 2214 2215 /* 2216 * truncate(char *path, int pad, off_t length) 2217 * 2218 * Truncate a file given its path name. 2219 */ 2220 int 2221 truncate(struct truncate_args *uap) 2222 { 2223 struct thread *td = curthread; 2224 struct nameidata nd; 2225 int error; 2226 2227 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); 2228 2229 error = kern_truncate(&nd, uap->length); 2230 2231 return error; 2232 } 2233 2234 int 2235 kern_ftruncate(int fd, off_t length) 2236 { 2237 struct thread *td = curthread; 2238 struct proc *p = td->td_proc; 2239 struct vattr vattr; 2240 struct vnode *vp; 2241 struct file *fp; 2242 int error; 2243 2244 if (length < 0) 2245 return(EINVAL); 2246 if ((error = getvnode(p->p_fd, fd, &fp)) != 0) 2247 return (error); 2248 if ((fp->f_flag & FWRITE) == 0) 2249 return (EINVAL); 2250 vp = (struct vnode *)fp->f_data; 2251 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2252 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2253 if (vp->v_type == VDIR) 2254 error = EISDIR; 2255 else if ((error = vn_writechk(vp)) == 0) { 2256 VATTR_NULL(&vattr); 2257 vattr.va_size = length; 2258 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td); 2259 } 2260 VOP_UNLOCK(vp, 0, td); 2261 return (error); 2262 } 2263 2264 /* 2265 * ftruncate_args(int fd, int pad, off_t length) 2266 * 2267 * Truncate a file given a file descriptor. 2268 */ 2269 int 2270 ftruncate(struct ftruncate_args *uap) 2271 { 2272 int error; 2273 2274 error = kern_ftruncate(uap->fd, uap->length); 2275 2276 return (error); 2277 } 2278 2279 /* 2280 * fsync(int fd) 2281 * 2282 * Sync an open file. 2283 */ 2284 /* ARGSUSED */ 2285 int 2286 fsync(struct fsync_args *uap) 2287 { 2288 struct thread *td = curthread; 2289 struct proc *p = td->td_proc; 2290 struct vnode *vp; 2291 struct file *fp; 2292 vm_object_t obj; 2293 int error; 2294 2295 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2296 return (error); 2297 vp = (struct vnode *)fp->f_data; 2298 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2299 if (VOP_GETVOBJECT(vp, &obj) == 0) 2300 vm_object_page_clean(obj, 0, 0, 0); 2301 if ((error = VOP_FSYNC(vp, MNT_WAIT, td)) == 0 && 2302 vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && 2303 bioops.io_fsync) 2304 error = (*bioops.io_fsync)(vp); 2305 VOP_UNLOCK(vp, 0, td); 2306 return (error); 2307 } 2308 2309 int 2310 kern_rename(struct nameidata *fromnd, struct nameidata *tond) 2311 { 2312 struct thread *td = curthread; 2313 struct proc *p = td->td_proc; 2314 struct vnode *tvp, *fvp, *tdvp; 2315 int error; 2316 2317 bwillwrite(); 2318 error = namei(fromnd); 2319 if (error) 2320 return (error); 2321 fvp = fromnd->ni_vp; 2322 if (fromnd->ni_vp->v_type == VDIR) 2323 tond->ni_cnd.cn_flags |= CNP_WILLBEDIR; 2324 error = namei(tond); 2325 if (error) { 2326 /* Translate error code for rename("dir1", "dir2/."). */ 2327 if (error == EISDIR && fvp->v_type == VDIR) 2328 error = EINVAL; 2329 NDFREE(fromnd, NDF_ONLY_PNBUF); 2330 vrele(fromnd->ni_dvp); 2331 vrele(fvp); 2332 goto out1; 2333 } 2334 tdvp = tond->ni_dvp; 2335 tvp = tond->ni_vp; 2336 if (tvp != NULL) { 2337 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2338 error = ENOTDIR; 2339 goto out; 2340 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2341 error = EISDIR; 2342 goto out; 2343 } 2344 } 2345 if (fvp == tdvp) 2346 error = EINVAL; 2347 /* 2348 * If the source is the same as the destination (that is, if they 2349 * are links to the same vnode), then there is nothing to do. 2350 */ 2351 if (fvp == tvp) 2352 error = -1; 2353 out: 2354 if (!error) { 2355 VOP_LEASE(tdvp, td, p->p_ucred, LEASE_WRITE); 2356 if (fromnd->ni_dvp != tdvp) { 2357 VOP_LEASE(fromnd->ni_dvp, td, p->p_ucred, LEASE_WRITE); 2358 } 2359 if (tvp) { 2360 VOP_LEASE(tvp, td, p->p_ucred, LEASE_WRITE); 2361 } 2362 error = VOP_RENAME(fromnd->ni_dvp, NCPNULL, fromnd->ni_vp, 2363 &fromnd->ni_cnd, tond->ni_dvp, NCPNULL, tond->ni_vp, 2364 &tond->ni_cnd); 2365 NDFREE(fromnd, NDF_ONLY_PNBUF); 2366 NDFREE(tond, NDF_ONLY_PNBUF); 2367 } else { 2368 NDFREE(fromnd, NDF_ONLY_PNBUF); 2369 NDFREE(tond, NDF_ONLY_PNBUF); 2370 if (tdvp == tvp) 2371 vrele(tdvp); 2372 else 2373 vput(tdvp); 2374 if (tvp) 2375 vput(tvp); 2376 vrele(fromnd->ni_dvp); 2377 vrele(fvp); 2378 } 2379 vrele(tond->ni_startdir); 2380 ASSERT_VOP_UNLOCKED(fromnd->ni_dvp, "rename"); 2381 ASSERT_VOP_UNLOCKED(fromnd->ni_vp, "rename"); 2382 ASSERT_VOP_UNLOCKED(tond->ni_dvp, "rename"); 2383 ASSERT_VOP_UNLOCKED(tond->ni_vp, "rename"); 2384 out1: 2385 if (fromnd->ni_startdir) 2386 vrele(fromnd->ni_startdir); 2387 if (error == -1) 2388 return (0); 2389 return (error); 2390 } 2391 2392 /* 2393 * rename_args(char *from, char *to) 2394 * 2395 * Rename files. Source and destination must either both be directories, 2396 * or both not be directories. If target is a directory, it must be empty. 2397 */ 2398 int 2399 rename(struct rename_args *uap) 2400 { 2401 struct thread *td = curthread; 2402 struct nameidata fromnd, tond; 2403 int error; 2404 2405 NDINIT(&fromnd, NAMEI_DELETE, CNP_WANTPARENT | CNP_SAVESTART, 2406 UIO_USERSPACE, uap->from, td); 2407 NDINIT(&tond, NAMEI_RENAME, 2408 CNP_LOCKPARENT | CNP_LOCKLEAF | CNP_NOCACHE | 2409 CNP_SAVESTART | CNP_NOOBJ, 2410 UIO_USERSPACE, uap->to, td); 2411 2412 error = kern_rename(&fromnd, &tond); 2413 2414 return (error); 2415 } 2416 2417 int 2418 kern_mkdir(struct nameidata *nd, int mode) 2419 { 2420 struct thread *td = curthread; 2421 struct proc *p = td->td_proc; 2422 struct vnode *vp; 2423 struct vattr vattr; 2424 int error; 2425 2426 bwillwrite(); 2427 nd->ni_cnd.cn_flags |= CNP_WILLBEDIR; 2428 error = namei(nd); 2429 if (error) 2430 return (error); 2431 vp = nd->ni_vp; 2432 if (vp) { 2433 NDFREE(nd, NDF_ONLY_PNBUF); 2434 if (nd->ni_dvp == vp) 2435 vrele(nd->ni_dvp); 2436 else 2437 vput(nd->ni_dvp); 2438 vrele(vp); 2439 return (EEXIST); 2440 } 2441 VATTR_NULL(&vattr); 2442 vattr.va_type = VDIR; 2443 vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask; 2444 VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); 2445 error = VOP_MKDIR(nd->ni_dvp, NCPNULL, &nd->ni_vp, &nd->ni_cnd, 2446 &vattr); 2447 NDFREE(nd, NDF_ONLY_PNBUF); 2448 vput(nd->ni_dvp); 2449 if (error == 0) 2450 vput(nd->ni_vp); 2451 ASSERT_VOP_UNLOCKED(nd->ni_dvp, "mkdir"); 2452 ASSERT_VOP_UNLOCKED(nd->ni_vp, "mkdir"); 2453 return (error); 2454 } 2455 2456 /* 2457 * mkdir_args(char *path, int mode) 2458 * 2459 * Make a directory file. 2460 */ 2461 /* ARGSUSED */ 2462 int 2463 mkdir(struct mkdir_args *uap) 2464 { 2465 struct thread *td = curthread; 2466 struct nameidata nd; 2467 int error; 2468 2469 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, uap->path, 2470 td); 2471 2472 error = kern_mkdir(&nd, uap->mode); 2473 2474 return (error); 2475 } 2476 2477 int 2478 kern_rmdir(struct nameidata *nd) 2479 { 2480 struct thread *td = curthread; 2481 struct proc *p = td->td_proc; 2482 struct vnode *vp; 2483 int error; 2484 2485 bwillwrite(); 2486 error = namei(nd); 2487 if (error) 2488 return (error); 2489 vp = nd->ni_vp; 2490 if (vp->v_type != VDIR) { 2491 error = ENOTDIR; 2492 goto out; 2493 } 2494 /* 2495 * No rmdir "." please. 2496 */ 2497 if (nd->ni_dvp == vp) { 2498 error = EINVAL; 2499 goto out; 2500 } 2501 /* 2502 * The root of a mounted filesystem cannot be deleted. 2503 */ 2504 if (vp->v_flag & VROOT) 2505 error = EBUSY; 2506 else { 2507 VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); 2508 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2509 error = VOP_RMDIR(nd->ni_dvp, NCPNULL, nd->ni_vp, 2510 &nd->ni_cnd); 2511 } 2512 out: 2513 NDFREE(nd, NDF_ONLY_PNBUF); 2514 if (nd->ni_dvp == vp) 2515 vrele(nd->ni_dvp); 2516 else 2517 vput(nd->ni_dvp); 2518 if (vp != NULLVP) 2519 vput(vp); 2520 ASSERT_VOP_UNLOCKED(nd->ni_dvp, "rmdir"); 2521 ASSERT_VOP_UNLOCKED(nd->ni_vp, "rmdir"); 2522 return (error); 2523 } 2524 2525 /* 2526 * rmdir_args(char *path) 2527 * 2528 * Remove a directory file. 2529 */ 2530 /* ARGSUSED */ 2531 int 2532 rmdir(struct rmdir_args *uap) 2533 { 2534 struct thread *td = curthread; 2535 struct nameidata nd; 2536 int error; 2537 2538 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_LOCKLEAF, 2539 UIO_USERSPACE, uap->path, td); 2540 2541 error = kern_rmdir(&nd); 2542 2543 return (error); 2544 } 2545 2546 int 2547 kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res) 2548 { 2549 struct thread *td = curthread; 2550 struct proc *p = td->td_proc; 2551 struct vnode *vp; 2552 struct file *fp; 2553 struct uio auio; 2554 struct iovec aiov; 2555 long loff; 2556 int error, eofflag; 2557 2558 if ((error = getvnode(p->p_fd, fd, &fp)) != 0) 2559 return (error); 2560 if ((fp->f_flag & FREAD) == 0) 2561 return (EBADF); 2562 vp = (struct vnode *)fp->f_data; 2563 unionread: 2564 if (vp->v_type != VDIR) 2565 return (EINVAL); 2566 aiov.iov_base = buf; 2567 aiov.iov_len = count; 2568 auio.uio_iov = &aiov; 2569 auio.uio_iovcnt = 1; 2570 auio.uio_rw = UIO_READ; 2571 auio.uio_segflg = UIO_USERSPACE; 2572 auio.uio_td = td; 2573 auio.uio_resid = count; 2574 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */ 2575 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2576 loff = auio.uio_offset = fp->f_offset; 2577 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 2578 fp->f_offset = auio.uio_offset; 2579 VOP_UNLOCK(vp, 0, td); 2580 if (error) 2581 return (error); 2582 if (count == auio.uio_resid) { 2583 if (union_dircheckp) { 2584 error = union_dircheckp(td, &vp, fp); 2585 if (error == -1) 2586 goto unionread; 2587 if (error) 2588 return (error); 2589 } 2590 if ((vp->v_flag & VROOT) && 2591 (vp->v_mount->mnt_flag & MNT_UNION)) { 2592 struct vnode *tvp = vp; 2593 vp = vp->v_mount->mnt_vnodecovered; 2594 VREF(vp); 2595 fp->f_data = (caddr_t) vp; 2596 fp->f_offset = 0; 2597 vrele(tvp); 2598 goto unionread; 2599 } 2600 } 2601 if (basep) { 2602 *basep = loff; 2603 } 2604 *res = count - auio.uio_resid; 2605 return (error); 2606 } 2607 2608 /* 2609 * getdirentries_args(int fd, char *buf, u_int conut, long *basep) 2610 * 2611 * Read a block of directory entries in a file system independent format. 2612 */ 2613 int 2614 getdirentries(struct getdirentries_args *uap) 2615 { 2616 long base; 2617 int error; 2618 2619 error = kern_getdirentries(uap->fd, uap->buf, uap->count, &base, 2620 &uap->sysmsg_result); 2621 2622 if (error == 0) 2623 error = copyout(&base, uap->basep, sizeof(*uap->basep)); 2624 return (error); 2625 } 2626 2627 /* 2628 * getdents_args(int fd, char *buf, size_t count) 2629 */ 2630 int 2631 getdents(struct getdents_args *uap) 2632 { 2633 int error; 2634 2635 error = kern_getdirentries(uap->fd, uap->buf, uap->count, NULL, 2636 &uap->sysmsg_result); 2637 2638 return (error); 2639 } 2640 2641 /* 2642 * umask(int newmask) 2643 * 2644 * Set the mode mask for creation of filesystem nodes. 2645 * 2646 * MP SAFE 2647 */ 2648 int 2649 umask(struct umask_args *uap) 2650 { 2651 struct thread *td = curthread; 2652 struct proc *p = td->td_proc; 2653 struct filedesc *fdp; 2654 2655 fdp = p->p_fd; 2656 uap->sysmsg_result = fdp->fd_cmask; 2657 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; 2658 return (0); 2659 } 2660 2661 /* 2662 * revoke(char *path) 2663 * 2664 * Void all references to file by ripping underlying filesystem 2665 * away from vnode. 2666 */ 2667 /* ARGSUSED */ 2668 int 2669 revoke(struct revoke_args *uap) 2670 { 2671 struct thread *td = curthread; 2672 struct proc *p = td->td_proc; 2673 struct vnode *vp; 2674 struct vattr vattr; 2675 int error; 2676 struct nameidata nd; 2677 2678 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 2679 if ((error = namei(&nd)) != 0) 2680 return (error); 2681 vp = nd.ni_vp; 2682 NDFREE(&nd, NDF_ONLY_PNBUF); 2683 if (vp->v_type != VCHR && vp->v_type != VBLK) { 2684 error = EINVAL; 2685 goto out; 2686 } 2687 if ((error = VOP_GETATTR(vp, &vattr, td)) != 0) 2688 goto out; 2689 if (p->p_ucred->cr_uid != vattr.va_uid && 2690 (error = suser_cred(p->p_ucred, PRISON_ROOT))) 2691 goto out; 2692 if (vcount(vp) > 1) 2693 VOP_REVOKE(vp, REVOKEALL); 2694 out: 2695 vrele(vp); 2696 return (error); 2697 } 2698 2699 /* 2700 * Convert a user file descriptor to a kernel file entry. 2701 */ 2702 int 2703 getvnode(struct filedesc *fdp, int fd, struct file **fpp) 2704 { 2705 struct file *fp; 2706 2707 if ((u_int)fd >= fdp->fd_nfiles || 2708 (fp = fdp->fd_ofiles[fd]) == NULL) 2709 return (EBADF); 2710 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) 2711 return (EINVAL); 2712 *fpp = fp; 2713 return (0); 2714 } 2715 /* 2716 * getfh_args(char *fname, fhandle_t *fhp) 2717 * 2718 * Get (NFS) file handle 2719 */ 2720 int 2721 getfh(struct getfh_args *uap) 2722 { 2723 struct thread *td = curthread; 2724 struct nameidata nd; 2725 fhandle_t fh; 2726 struct vnode *vp; 2727 int error; 2728 2729 /* 2730 * Must be super user 2731 */ 2732 error = suser(td); 2733 if (error) 2734 return (error); 2735 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, uap->fname, td); 2736 error = namei(&nd); 2737 if (error) 2738 return (error); 2739 NDFREE(&nd, NDF_ONLY_PNBUF); 2740 vp = nd.ni_vp; 2741 bzero(&fh, sizeof(fh)); 2742 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 2743 error = VFS_VPTOFH(vp, &fh.fh_fid); 2744 vput(vp); 2745 if (error) 2746 return (error); 2747 error = copyout(&fh, uap->fhp, sizeof (fh)); 2748 return (error); 2749 } 2750 2751 /* 2752 * fhopen_args(const struct fhandle *u_fhp, int flags) 2753 * 2754 * syscall for the rpc.lockd to use to translate a NFS file handle into 2755 * an open descriptor. 2756 * 2757 * warning: do not remove the suser() call or this becomes one giant 2758 * security hole. 2759 */ 2760 int 2761 fhopen(struct fhopen_args *uap) 2762 { 2763 struct thread *td = curthread; 2764 struct proc *p = td->td_proc; 2765 struct mount *mp; 2766 struct vnode *vp; 2767 struct fhandle fhp; 2768 struct vattr vat; 2769 struct vattr *vap = &vat; 2770 struct flock lf; 2771 struct file *fp; 2772 struct filedesc *fdp = p->p_fd; 2773 int fmode, mode, error, type; 2774 struct file *nfp; 2775 int indx; 2776 2777 /* 2778 * Must be super user 2779 */ 2780 error = suser(td); 2781 if (error) 2782 return (error); 2783 2784 fmode = FFLAGS(SCARG(uap, flags)); 2785 /* why not allow a non-read/write open for our lockd? */ 2786 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 2787 return (EINVAL); 2788 error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp)); 2789 if (error) 2790 return(error); 2791 /* find the mount point */ 2792 mp = vfs_getvfs(&fhp.fh_fsid); 2793 if (mp == NULL) 2794 return (ESTALE); 2795 /* now give me my vnode, it gets returned to me locked */ 2796 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 2797 if (error) 2798 return (error); 2799 /* 2800 * from now on we have to make sure not 2801 * to forget about the vnode 2802 * any error that causes an abort must vput(vp) 2803 * just set error = err and 'goto bad;'. 2804 */ 2805 2806 /* 2807 * from vn_open 2808 */ 2809 if (vp->v_type == VLNK) { 2810 error = EMLINK; 2811 goto bad; 2812 } 2813 if (vp->v_type == VSOCK) { 2814 error = EOPNOTSUPP; 2815 goto bad; 2816 } 2817 mode = 0; 2818 if (fmode & (FWRITE | O_TRUNC)) { 2819 if (vp->v_type == VDIR) { 2820 error = EISDIR; 2821 goto bad; 2822 } 2823 error = vn_writechk(vp); 2824 if (error) 2825 goto bad; 2826 mode |= VWRITE; 2827 } 2828 if (fmode & FREAD) 2829 mode |= VREAD; 2830 if (mode) { 2831 error = VOP_ACCESS(vp, mode, p->p_ucred, td); 2832 if (error) 2833 goto bad; 2834 } 2835 if (fmode & O_TRUNC) { 2836 VOP_UNLOCK(vp, 0, td); /* XXX */ 2837 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); 2838 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */ 2839 VATTR_NULL(vap); 2840 vap->va_size = 0; 2841 error = VOP_SETATTR(vp, vap, p->p_ucred, td); 2842 if (error) 2843 goto bad; 2844 } 2845 error = VOP_OPEN(vp, fmode, p->p_ucred, td); 2846 if (error) 2847 goto bad; 2848 /* 2849 * Make sure that a VM object is created for VMIO support. 2850 */ 2851 if (vn_canvmio(vp) == TRUE) { 2852 if ((error = vfs_object_create(vp, td)) != 0) 2853 goto bad; 2854 } 2855 if (fmode & FWRITE) 2856 vp->v_writecount++; 2857 2858 /* 2859 * end of vn_open code 2860 */ 2861 2862 if ((error = falloc(p, &nfp, &indx)) != 0) { 2863 if (fmode & FWRITE) 2864 vp->v_writecount--; 2865 goto bad; 2866 } 2867 fp = nfp; 2868 2869 /* 2870 * hold an extra reference to avoid having fp ripped out 2871 * from under us while we block in the lock op. 2872 */ 2873 fhold(fp); 2874 nfp->f_data = (caddr_t)vp; 2875 nfp->f_flag = fmode & FMASK; 2876 nfp->f_ops = &vnops; 2877 nfp->f_type = DTYPE_VNODE; 2878 if (fmode & (O_EXLOCK | O_SHLOCK)) { 2879 lf.l_whence = SEEK_SET; 2880 lf.l_start = 0; 2881 lf.l_len = 0; 2882 if (fmode & O_EXLOCK) 2883 lf.l_type = F_WRLCK; 2884 else 2885 lf.l_type = F_RDLCK; 2886 type = F_FLOCK; 2887 if ((fmode & FNONBLOCK) == 0) 2888 type |= F_WAIT; 2889 VOP_UNLOCK(vp, 0, td); 2890 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 2891 /* 2892 * lock request failed. Normally close the descriptor 2893 * but handle the case where someone might have dup()d 2894 * or close()d it when we weren't looking. 2895 */ 2896 if (fdp->fd_ofiles[indx] == fp) { 2897 fdp->fd_ofiles[indx] = NULL; 2898 fdrop(fp, td); 2899 } 2900 2901 /* 2902 * release our private reference. 2903 */ 2904 fdrop(fp, td); 2905 return (error); 2906 } 2907 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2908 fp->f_flag |= FHASLOCK; 2909 } 2910 if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0)) 2911 vfs_object_create(vp, td); 2912 2913 VOP_UNLOCK(vp, 0, td); 2914 fdrop(fp, td); 2915 uap->sysmsg_result = indx; 2916 return (0); 2917 2918 bad: 2919 vput(vp); 2920 return (error); 2921 } 2922 2923 /* 2924 * fhstat_args(struct fhandle *u_fhp, struct stat *sb) 2925 */ 2926 int 2927 fhstat(struct fhstat_args *uap) 2928 { 2929 struct thread *td = curthread; 2930 struct stat sb; 2931 fhandle_t fh; 2932 struct mount *mp; 2933 struct vnode *vp; 2934 int error; 2935 2936 /* 2937 * Must be super user 2938 */ 2939 error = suser(td); 2940 if (error) 2941 return (error); 2942 2943 error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t)); 2944 if (error) 2945 return (error); 2946 2947 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 2948 return (ESTALE); 2949 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 2950 return (error); 2951 error = vn_stat(vp, &sb, td); 2952 vput(vp); 2953 if (error) 2954 return (error); 2955 error = copyout(&sb, SCARG(uap, sb), sizeof(sb)); 2956 return (error); 2957 } 2958 2959 /* 2960 * fhstatfs_args(struct fhandle *u_fhp, struct statfs *buf) 2961 */ 2962 int 2963 fhstatfs(struct fhstatfs_args *uap) 2964 { 2965 struct thread *td = curthread; 2966 struct statfs *sp; 2967 struct mount *mp; 2968 struct vnode *vp; 2969 struct statfs sb; 2970 fhandle_t fh; 2971 int error; 2972 2973 /* 2974 * Must be super user 2975 */ 2976 if ((error = suser(td))) 2977 return (error); 2978 2979 if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0) 2980 return (error); 2981 2982 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 2983 return (ESTALE); 2984 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 2985 return (error); 2986 mp = vp->v_mount; 2987 sp = &mp->mnt_stat; 2988 vput(vp); 2989 if ((error = VFS_STATFS(mp, sp, td)) != 0) 2990 return (error); 2991 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 2992 if (suser(td)) { 2993 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 2994 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 2995 sp = &sb; 2996 } 2997 return (copyout(sp, SCARG(uap, buf), sizeof(*sp))); 2998 } 2999 3000 /* 3001 * Syscall to push extended attribute configuration information into the 3002 * VFS. Accepts a path, which it converts to a mountpoint, as well as 3003 * a command (int cmd), and attribute name and misc data. For now, the 3004 * attribute name is left in userspace for consumption by the VFS_op. 3005 * It will probably be changed to be copied into sysspace by the 3006 * syscall in the future, once issues with various consumers of the 3007 * attribute code have raised their hands. 3008 * 3009 * Currently this is used only by UFS Extended Attributes. 3010 */ 3011 int 3012 extattrctl(struct extattrctl_args *uap) 3013 { 3014 struct thread *td = curthread; 3015 struct nameidata nd; 3016 struct mount *mp; 3017 int error; 3018 3019 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 3020 if ((error = namei(&nd)) != 0) 3021 return (error); 3022 mp = nd.ni_vp->v_mount; 3023 NDFREE(&nd, 0); 3024 return (VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname), 3025 SCARG(uap, arg), td)); 3026 } 3027 3028 /* 3029 * Syscall to set a named extended attribute on a file or directory. 3030 * Accepts attribute name, and a uio structure pointing to the data to set. 3031 * The uio is consumed in the style of writev(). The real work happens 3032 * in VOP_SETEXTATTR(). 3033 */ 3034 int 3035 extattr_set_file(struct extattr_set_file_args *uap) 3036 { 3037 struct thread *td = curthread; 3038 struct proc *p = td->td_proc; 3039 struct nameidata nd; 3040 struct uio auio; 3041 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 3042 char attrname[EXTATTR_MAXNAMELEN]; 3043 u_int iovlen, cnt; 3044 int error, i; 3045 3046 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3047 if (error) 3048 return (error); 3049 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3050 SCARG(uap, path), td); 3051 if ((error = namei(&nd)) != 0) 3052 return(error); 3053 iovlen = uap->iovcnt * sizeof(struct iovec); 3054 if (uap->iovcnt > UIO_SMALLIOV) { 3055 if (uap->iovcnt > UIO_MAXIOV) { 3056 error = EINVAL; 3057 goto done; 3058 } 3059 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3060 needfree = iov; 3061 } else 3062 iov = aiov; 3063 auio.uio_iov = iov; 3064 auio.uio_iovcnt = uap->iovcnt; 3065 auio.uio_rw = UIO_WRITE; 3066 auio.uio_segflg = UIO_USERSPACE; 3067 auio.uio_td = td; 3068 auio.uio_offset = 0; 3069 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3070 goto done; 3071 auio.uio_resid = 0; 3072 for (i = 0; i < uap->iovcnt; i++) { 3073 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3074 error = EINVAL; 3075 goto done; 3076 } 3077 auio.uio_resid += iov->iov_len; 3078 iov++; 3079 } 3080 cnt = auio.uio_resid; 3081 error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td); 3082 cnt -= auio.uio_resid; 3083 uap->sysmsg_result = cnt; 3084 done: 3085 if (needfree) 3086 FREE(needfree, M_IOV); 3087 NDFREE(&nd, 0); 3088 return (error); 3089 } 3090 3091 /* 3092 * Syscall to get a named extended attribute on a file or directory. 3093 * Accepts attribute name, and a uio structure pointing to a buffer for the 3094 * data. The uio is consumed in the style of readv(). The real work 3095 * happens in VOP_GETEXTATTR(); 3096 */ 3097 int 3098 extattr_get_file(struct extattr_get_file_args *uap) 3099 { 3100 struct thread *td = curthread; 3101 struct proc *p = td->td_proc; 3102 struct nameidata nd; 3103 struct uio auio; 3104 struct iovec *iov, *needfree, aiov[UIO_SMALLIOV]; 3105 char attrname[EXTATTR_MAXNAMELEN]; 3106 u_int iovlen, cnt; 3107 int error, i; 3108 3109 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3110 if (error) 3111 return (error); 3112 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3113 SCARG(uap, path), td); 3114 if ((error = namei(&nd)) != 0) 3115 return (error); 3116 iovlen = uap->iovcnt * sizeof (struct iovec); 3117 if (uap->iovcnt > UIO_SMALLIOV) { 3118 if (uap->iovcnt > UIO_MAXIOV) { 3119 NDFREE(&nd, 0); 3120 return (EINVAL); 3121 } 3122 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3123 needfree = iov; 3124 } else { 3125 iov = aiov; 3126 needfree = NULL; 3127 } 3128 auio.uio_iov = iov; 3129 auio.uio_iovcnt = uap->iovcnt; 3130 auio.uio_rw = UIO_READ; 3131 auio.uio_segflg = UIO_USERSPACE; 3132 auio.uio_td = td; 3133 auio.uio_offset = 0; 3134 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3135 goto done; 3136 auio.uio_resid = 0; 3137 for (i = 0; i < uap->iovcnt; i++) { 3138 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3139 error = EINVAL; 3140 goto done; 3141 } 3142 auio.uio_resid += iov->iov_len; 3143 iov++; 3144 } 3145 cnt = auio.uio_resid; 3146 error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td); 3147 cnt -= auio.uio_resid; 3148 uap->sysmsg_result = cnt; 3149 done: 3150 if (needfree) 3151 FREE(needfree, M_IOV); 3152 NDFREE(&nd, 0); 3153 return(error); 3154 } 3155 3156 /* 3157 * Syscall to delete a named extended attribute from a file or directory. 3158 * Accepts attribute name. The real work happens in VOP_SETEXTATTR(). 3159 */ 3160 int 3161 extattr_delete_file(struct extattr_delete_file_args *uap) 3162 { 3163 struct thread *td = curthread; 3164 struct proc *p = td->td_proc; 3165 struct nameidata nd; 3166 char attrname[EXTATTR_MAXNAMELEN]; 3167 int error; 3168 3169 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3170 if (error) 3171 return(error); 3172 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, 3173 SCARG(uap, path), td); 3174 if ((error = namei(&nd)) != 0) 3175 return(error); 3176 error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_ucred, td); 3177 NDFREE(&nd, 0); 3178 return(error); 3179 } 3180