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$ 40 */ 41 42 /* For 4.3 integer FS ID compatibility */ 43 #include "opt_compat.h" 44 #include "opt_mac.h" 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/bio.h> 49 #include <sys/buf.h> 50 #include <sys/sysent.h> 51 #include <sys/mac.h> 52 #include <sys/malloc.h> 53 #include <sys/mount.h> 54 #include <sys/mutex.h> 55 #include <sys/sysproto.h> 56 #include <sys/namei.h> 57 #include <sys/filedesc.h> 58 #include <sys/kernel.h> 59 #include <sys/fcntl.h> 60 #include <sys/file.h> 61 #include <sys/linker.h> 62 #include <sys/stat.h> 63 #include <sys/sx.h> 64 #include <sys/unistd.h> 65 #include <sys/vnode.h> 66 #include <sys/proc.h> 67 #include <sys/dirent.h> 68 #include <sys/extattr.h> 69 #include <sys/jail.h> 70 #include <sys/syscallsubr.h> 71 #include <sys/sysctl.h> 72 73 #include <machine/limits.h> 74 #include <machine/stdarg.h> 75 76 #include <vm/vm.h> 77 #include <vm/vm_object.h> 78 #include <vm/vm_page.h> 79 #include <vm/uma.h> 80 81 static int change_dir(struct nameidata *ndp, struct thread *td); 82 static int chroot_refuse_vdir_fds(struct filedesc *fdp); 83 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); 84 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t); 85 static int setfmode(struct thread *td, struct vnode *, int); 86 static int setfflags(struct thread *td, struct vnode *, int); 87 static int setutimes(struct thread *td, struct vnode *, 88 const struct timespec *, int, int); 89 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, 90 struct thread *td); 91 92 int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *); 93 int (*softdep_fsync_hook)(struct vnode *); 94 95 /* 96 * The module initialization routine for POSIX asynchronous I/O will 97 * set this to the version of AIO that it implements. (Zero means 98 * that it is not implemented.) This value is used here by pathconf() 99 * and in kern_descrip.c by fpathconf(). 100 */ 101 int async_io_version; 102 103 /* 104 * Sync each mounted filesystem. 105 */ 106 #ifndef _SYS_SYSPROTO_H_ 107 struct sync_args { 108 int dummy; 109 }; 110 #endif 111 112 #ifdef DEBUG 113 static int syncprt = 0; 114 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 115 #endif 116 117 /* ARGSUSED */ 118 int 119 sync(td, uap) 120 struct thread *td; 121 struct sync_args *uap; 122 { 123 struct mount *mp, *nmp; 124 int asyncflag; 125 126 mtx_lock(&mountlist_mtx); 127 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { 128 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) { 129 nmp = TAILQ_NEXT(mp, mnt_list); 130 continue; 131 } 132 if ((mp->mnt_flag & MNT_RDONLY) == 0 && 133 vn_start_write(NULL, &mp, V_NOWAIT) == 0) { 134 asyncflag = mp->mnt_flag & MNT_ASYNC; 135 mp->mnt_flag &= ~MNT_ASYNC; 136 vfs_msync(mp, MNT_NOWAIT); 137 VFS_SYNC(mp, MNT_NOWAIT, 138 ((td != NULL) ? td->td_ucred : NOCRED), td); 139 mp->mnt_flag |= asyncflag; 140 vn_finished_write(mp); 141 } 142 mtx_lock(&mountlist_mtx); 143 nmp = TAILQ_NEXT(mp, mnt_list); 144 vfs_unbusy(mp, td); 145 } 146 mtx_unlock(&mountlist_mtx); 147 #if 0 148 /* 149 * XXX don't call vfs_bufstats() yet because that routine 150 * was not imported in the Lite2 merge. 151 */ 152 #ifdef DIAGNOSTIC 153 if (syncprt) 154 vfs_bufstats(); 155 #endif /* DIAGNOSTIC */ 156 #endif 157 return (0); 158 } 159 160 /* XXX PRISON: could be per prison flag */ 161 static int prison_quotas; 162 #if 0 163 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 164 #endif 165 166 /* 167 * Change filesystem quotas. 168 */ 169 #ifndef _SYS_SYSPROTO_H_ 170 struct quotactl_args { 171 char *path; 172 int cmd; 173 int uid; 174 caddr_t arg; 175 }; 176 #endif 177 /* ARGSUSED */ 178 int 179 quotactl(td, uap) 180 struct thread *td; 181 register struct quotactl_args /* { 182 char *path; 183 int cmd; 184 int uid; 185 caddr_t arg; 186 } */ *uap; 187 { 188 struct mount *mp; 189 int error; 190 struct nameidata nd; 191 192 if (jailed(td->td_ucred) && !prison_quotas) 193 return (EPERM); 194 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 195 if ((error = namei(&nd)) != 0) 196 return (error); 197 NDFREE(&nd, NDF_ONLY_PNBUF); 198 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 199 vrele(nd.ni_vp); 200 if (error) 201 return (error); 202 error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td); 203 vn_finished_write(mp); 204 return (error); 205 } 206 207 /* 208 * Get filesystem statistics. 209 */ 210 #ifndef _SYS_SYSPROTO_H_ 211 struct statfs_args { 212 char *path; 213 struct statfs *buf; 214 }; 215 #endif 216 /* ARGSUSED */ 217 int 218 statfs(td, uap) 219 struct thread *td; 220 register struct statfs_args /* { 221 char *path; 222 struct statfs *buf; 223 } */ *uap; 224 { 225 register struct mount *mp; 226 register struct statfs *sp; 227 int error; 228 struct nameidata nd; 229 struct statfs sb; 230 231 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 232 if ((error = namei(&nd)) != 0) 233 return (error); 234 mp = nd.ni_vp->v_mount; 235 sp = &mp->mnt_stat; 236 NDFREE(&nd, NDF_ONLY_PNBUF); 237 vrele(nd.ni_vp); 238 #ifdef MAC 239 error = mac_check_mount_stat(td->td_ucred, mp); 240 if (error) 241 return (error); 242 #endif 243 error = VFS_STATFS(mp, sp, td); 244 if (error) 245 return (error); 246 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 247 if (suser(td)) { 248 bcopy(sp, &sb, sizeof(sb)); 249 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 250 sp = &sb; 251 } 252 return (copyout(sp, uap->buf, sizeof(*sp))); 253 } 254 255 /* 256 * Get filesystem statistics. 257 */ 258 #ifndef _SYS_SYSPROTO_H_ 259 struct fstatfs_args { 260 int fd; 261 struct statfs *buf; 262 }; 263 #endif 264 /* ARGSUSED */ 265 int 266 fstatfs(td, uap) 267 struct thread *td; 268 register struct fstatfs_args /* { 269 int fd; 270 struct statfs *buf; 271 } */ *uap; 272 { 273 struct file *fp; 274 struct mount *mp; 275 register struct statfs *sp; 276 int error; 277 struct statfs sb; 278 279 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 280 return (error); 281 mp = ((struct vnode *)fp->f_data)->v_mount; 282 fdrop(fp, td); 283 if (mp == NULL) 284 return (EBADF); 285 #ifdef MAC 286 error = mac_check_mount_stat(td->td_ucred, mp); 287 if (error) 288 return (error); 289 #endif 290 sp = &mp->mnt_stat; 291 error = VFS_STATFS(mp, sp, td); 292 if (error) 293 return (error); 294 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 295 if (suser(td)) { 296 bcopy(sp, &sb, sizeof(sb)); 297 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 298 sp = &sb; 299 } 300 return (copyout(sp, uap->buf, sizeof(*sp))); 301 } 302 303 /* 304 * Get statistics on all filesystems. 305 */ 306 #ifndef _SYS_SYSPROTO_H_ 307 struct getfsstat_args { 308 struct statfs *buf; 309 long bufsize; 310 int flags; 311 }; 312 #endif 313 int 314 getfsstat(td, uap) 315 struct thread *td; 316 register struct getfsstat_args /* { 317 struct statfs *buf; 318 long bufsize; 319 int flags; 320 } */ *uap; 321 { 322 register struct mount *mp, *nmp; 323 register struct statfs *sp; 324 caddr_t sfsp; 325 long count, maxcount, error; 326 327 maxcount = uap->bufsize / sizeof(struct statfs); 328 sfsp = (caddr_t)uap->buf; 329 count = 0; 330 mtx_lock(&mountlist_mtx); 331 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { 332 #ifdef MAC 333 if (mac_check_mount_stat(td->td_ucred, mp) != 0) { 334 nmp = TAILQ_NEXT(mp, mnt_list); 335 continue; 336 } 337 #endif 338 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) { 339 nmp = TAILQ_NEXT(mp, mnt_list); 340 continue; 341 } 342 if (sfsp && count < maxcount) { 343 sp = &mp->mnt_stat; 344 /* 345 * If MNT_NOWAIT or MNT_LAZY is specified, do not 346 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 347 * overrides MNT_WAIT. 348 */ 349 if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || 350 (uap->flags & MNT_WAIT)) && 351 (error = VFS_STATFS(mp, sp, td))) { 352 mtx_lock(&mountlist_mtx); 353 nmp = TAILQ_NEXT(mp, mnt_list); 354 vfs_unbusy(mp, td); 355 continue; 356 } 357 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 358 error = copyout(sp, sfsp, sizeof(*sp)); 359 if (error) { 360 vfs_unbusy(mp, td); 361 return (error); 362 } 363 sfsp += sizeof(*sp); 364 } 365 count++; 366 mtx_lock(&mountlist_mtx); 367 nmp = TAILQ_NEXT(mp, mnt_list); 368 vfs_unbusy(mp, td); 369 } 370 mtx_unlock(&mountlist_mtx); 371 if (sfsp && count > maxcount) 372 td->td_retval[0] = maxcount; 373 else 374 td->td_retval[0] = count; 375 return (0); 376 } 377 378 /* 379 * Change current working directory to a given file descriptor. 380 */ 381 #ifndef _SYS_SYSPROTO_H_ 382 struct fchdir_args { 383 int fd; 384 }; 385 #endif 386 /* ARGSUSED */ 387 int 388 fchdir(td, uap) 389 struct thread *td; 390 struct fchdir_args /* { 391 int fd; 392 } */ *uap; 393 { 394 register struct filedesc *fdp = td->td_proc->p_fd; 395 struct vnode *vp, *tdp, *vpold; 396 struct mount *mp; 397 struct file *fp; 398 int error; 399 400 if ((error = getvnode(fdp, uap->fd, &fp)) != 0) 401 return (error); 402 vp = fp->f_data; 403 VREF(vp); 404 fdrop(fp, td); 405 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 406 if (vp->v_type != VDIR) 407 error = ENOTDIR; 408 #ifdef MAC 409 else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) { 410 } 411 #endif 412 else 413 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); 414 while (!error && (mp = vp->v_mountedhere) != NULL) { 415 if (vfs_busy(mp, 0, 0, td)) 416 continue; 417 error = VFS_ROOT(mp, &tdp); 418 vfs_unbusy(mp, td); 419 if (error) 420 break; 421 vput(vp); 422 vp = tdp; 423 } 424 if (error) { 425 vput(vp); 426 return (error); 427 } 428 VOP_UNLOCK(vp, 0, td); 429 FILEDESC_LOCK(fdp); 430 vpold = fdp->fd_cdir; 431 fdp->fd_cdir = vp; 432 FILEDESC_UNLOCK(fdp); 433 vrele(vpold); 434 return (0); 435 } 436 437 /* 438 * Change current working directory (``.''). 439 */ 440 #ifndef _SYS_SYSPROTO_H_ 441 struct chdir_args { 442 char *path; 443 }; 444 #endif 445 /* ARGSUSED */ 446 int 447 chdir(td, uap) 448 struct thread *td; 449 struct chdir_args /* { 450 char *path; 451 } */ *uap; 452 { 453 454 return (kern_chdir(td, uap->path, UIO_USERSPACE)); 455 } 456 457 int 458 kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) 459 { 460 register struct filedesc *fdp = td->td_proc->p_fd; 461 int error; 462 struct nameidata nd; 463 struct vnode *vp; 464 465 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pathseg, path, td); 466 if ((error = change_dir(&nd, td)) != 0) 467 return (error); 468 VOP_UNLOCK(nd.ni_vp, 0, td); 469 NDFREE(&nd, NDF_ONLY_PNBUF); 470 FILEDESC_LOCK(fdp); 471 vp = fdp->fd_cdir; 472 fdp->fd_cdir = nd.ni_vp; 473 FILEDESC_UNLOCK(fdp); 474 vrele(vp); 475 return (0); 476 } 477 478 /* 479 * Helper function for raised chroot(2) security function: Refuse if 480 * any filedescriptors are open directories. 481 */ 482 static int 483 chroot_refuse_vdir_fds(fdp) 484 struct filedesc *fdp; 485 { 486 struct vnode *vp; 487 struct file *fp; 488 int fd; 489 490 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); 491 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 492 fp = fget_locked(fdp, fd); 493 if (fp == NULL) 494 continue; 495 if (fp->f_type == DTYPE_VNODE) { 496 vp = fp->f_data; 497 if (vp->v_type == VDIR) 498 return (EPERM); 499 } 500 } 501 return (0); 502 } 503 504 /* 505 * This sysctl determines if we will allow a process to chroot(2) if it 506 * has a directory open: 507 * 0: disallowed for all processes. 508 * 1: allowed for processes that were not already chroot(2)'ed. 509 * 2: allowed for all processes. 510 */ 511 512 static int chroot_allow_open_directories = 1; 513 514 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 515 &chroot_allow_open_directories, 0, ""); 516 517 /* 518 * Change notion of root (``/'') directory. 519 */ 520 #ifndef _SYS_SYSPROTO_H_ 521 struct chroot_args { 522 char *path; 523 }; 524 #endif 525 /* ARGSUSED */ 526 int 527 chroot(td, uap) 528 struct thread *td; 529 struct chroot_args /* { 530 char *path; 531 } */ *uap; 532 { 533 register struct filedesc *fdp = td->td_proc->p_fd; 534 int error; 535 struct nameidata nd; 536 struct vnode *vp; 537 538 error = suser_cred(td->td_ucred, PRISON_ROOT); 539 if (error) 540 return (error); 541 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, td); 542 mtx_lock(&Giant); 543 if ((error = change_dir(&nd, td)) != 0) 544 goto error; 545 #ifdef MAC 546 if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp))) { 547 vput(nd.ni_vp); 548 goto error; 549 } 550 #endif 551 VOP_UNLOCK(nd.ni_vp, 0, td); 552 FILEDESC_LOCK(fdp); 553 if (chroot_allow_open_directories == 0 || 554 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { 555 error = chroot_refuse_vdir_fds(fdp); 556 if (error) 557 goto error_unlock; 558 } 559 vp = fdp->fd_rdir; 560 fdp->fd_rdir = nd.ni_vp; 561 if (!fdp->fd_jdir) { 562 fdp->fd_jdir = nd.ni_vp; 563 VREF(fdp->fd_jdir); 564 } 565 FILEDESC_UNLOCK(fdp); 566 NDFREE(&nd, NDF_ONLY_PNBUF); 567 vrele(vp); 568 mtx_unlock(&Giant); 569 return (0); 570 error_unlock: 571 FILEDESC_UNLOCK(fdp); 572 error: 573 mtx_unlock(&Giant); 574 NDFREE(&nd, NDF_ONLY_PNBUF); 575 return (error); 576 } 577 578 /* 579 * Common routine for chroot and chdir. On success, the directory vnode 580 * is returned locked, and must be unlocked by the caller. 581 */ 582 static int 583 change_dir(ndp, td) 584 register struct nameidata *ndp; 585 struct thread *td; 586 { 587 struct vnode *vp; 588 int error; 589 590 error = namei(ndp); 591 if (error) 592 return (error); 593 vp = ndp->ni_vp; 594 if (vp->v_type != VDIR) 595 error = ENOTDIR; 596 #ifdef MAC 597 if (error == 0) 598 error = mac_check_vnode_chdir(td->td_ucred, vp); 599 #endif 600 if (error == 0) 601 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); 602 if (error) 603 vput(vp); 604 return (error); 605 } 606 607 /* 608 * Check permissions, allocate an open file structure, 609 * and call the device open routine if any. 610 */ 611 #ifndef _SYS_SYSPROTO_H_ 612 struct open_args { 613 char *path; 614 int flags; 615 int mode; 616 }; 617 #endif 618 int 619 open(td, uap) 620 struct thread *td; 621 register struct open_args /* { 622 char *path; 623 int flags; 624 int mode; 625 } */ *uap; 626 { 627 628 return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); 629 } 630 631 int 632 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, 633 int mode) 634 { 635 struct proc *p = td->td_proc; 636 struct filedesc *fdp = p->p_fd; 637 struct file *fp; 638 struct vnode *vp; 639 struct vattr vat; 640 struct mount *mp; 641 int cmode, oflags; 642 struct file *nfp; 643 int type, indx, error; 644 struct flock lf; 645 struct nameidata nd; 646 647 if ((flags & O_ACCMODE) == O_ACCMODE) 648 return (EINVAL); 649 oflags = flags; 650 flags = FFLAGS(flags); 651 error = falloc(td, &nfp, &indx); 652 if (error) 653 return (error); 654 fp = nfp; 655 cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 656 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); 657 td->td_dupfd = -indx - 1; /* XXX check for fdopen */ 658 /* 659 * Bump the ref count to prevent another process from closing 660 * the descriptor while we are blocked in vn_open() 661 */ 662 fhold(fp); 663 error = vn_open(&nd, &flags, cmode); 664 if (error) { 665 /* 666 * release our own reference 667 */ 668 fdrop(fp, td); 669 670 /* 671 * handle special fdopen() case. bleh. dupfdopen() is 672 * responsible for dropping the old contents of ofiles[indx] 673 * if it succeeds. 674 */ 675 if ((error == ENODEV || error == ENXIO) && 676 td->td_dupfd >= 0 && /* XXX from fdopen */ 677 (error = 678 dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) { 679 td->td_retval[0] = indx; 680 return (0); 681 } 682 /* 683 * Clean up the descriptor, but only if another thread hadn't 684 * replaced or closed it. 685 */ 686 FILEDESC_LOCK(fdp); 687 if (fdp->fd_ofiles[indx] == fp) { 688 fdp->fd_ofiles[indx] = NULL; 689 FILEDESC_UNLOCK(fdp); 690 fdrop(fp, td); 691 } else 692 FILEDESC_UNLOCK(fdp); 693 694 if (error == ERESTART) 695 error = EINTR; 696 return (error); 697 } 698 td->td_dupfd = 0; 699 NDFREE(&nd, NDF_ONLY_PNBUF); 700 vp = nd.ni_vp; 701 702 /* 703 * There should be 2 references on the file, one from the descriptor 704 * table, and one for us. 705 * 706 * Handle the case where someone closed the file (via its file 707 * descriptor) while we were blocked. The end result should look 708 * like opening the file succeeded but it was immediately closed. 709 */ 710 FILEDESC_LOCK(fdp); 711 FILE_LOCK(fp); 712 if (fp->f_count == 1) { 713 KASSERT(fdp->fd_ofiles[indx] != fp, 714 ("Open file descriptor lost all refs")); 715 FILEDESC_UNLOCK(fdp); 716 FILE_UNLOCK(fp); 717 VOP_UNLOCK(vp, 0, td); 718 vn_close(vp, flags & FMASK, fp->f_cred, td); 719 fdrop(fp, td); 720 td->td_retval[0] = indx; 721 return 0; 722 } 723 724 /* assert that vn_open created a backing object if one is needed */ 725 KASSERT(!vn_canvmio(vp) || VOP_GETVOBJECT(vp, NULL) == 0, 726 ("open: vmio vnode has no backing object after vn_open")); 727 728 fp->f_data = vp; 729 fp->f_flag = flags & FMASK; 730 fp->f_ops = &vnops; 731 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); 732 FILEDESC_UNLOCK(fdp); 733 FILE_UNLOCK(fp); 734 VOP_UNLOCK(vp, 0, td); 735 if (flags & (O_EXLOCK | O_SHLOCK)) { 736 lf.l_whence = SEEK_SET; 737 lf.l_start = 0; 738 lf.l_len = 0; 739 if (flags & O_EXLOCK) 740 lf.l_type = F_WRLCK; 741 else 742 lf.l_type = F_RDLCK; 743 type = F_FLOCK; 744 if ((flags & FNONBLOCK) == 0) 745 type |= F_WAIT; 746 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 747 type)) != 0) 748 goto bad; 749 fp->f_flag |= FHASLOCK; 750 } 751 if (flags & O_TRUNC) { 752 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 753 goto bad; 754 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 755 VATTR_NULL(&vat); 756 vat.va_size = 0; 757 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 758 #ifdef MAC 759 error = mac_check_vnode_write(td->td_ucred, fp->f_cred, vp); 760 if (error == 0) 761 #endif 762 error = VOP_SETATTR(vp, &vat, td->td_ucred, td); 763 VOP_UNLOCK(vp, 0, td); 764 vn_finished_write(mp); 765 if (error) 766 goto bad; 767 } 768 /* 769 * Release our private reference, leaving the one associated with 770 * the descriptor table intact. 771 */ 772 fdrop(fp, td); 773 td->td_retval[0] = indx; 774 return (0); 775 bad: 776 FILEDESC_LOCK(fdp); 777 if (fdp->fd_ofiles[indx] == fp) { 778 fdp->fd_ofiles[indx] = NULL; 779 FILEDESC_UNLOCK(fdp); 780 fdrop(fp, td); 781 } else 782 FILEDESC_UNLOCK(fdp); 783 fdrop(fp, td); 784 return (error); 785 } 786 787 #ifdef COMPAT_43 788 /* 789 * Create a file. 790 */ 791 #ifndef _SYS_SYSPROTO_H_ 792 struct ocreat_args { 793 char *path; 794 int mode; 795 }; 796 #endif 797 int 798 ocreat(td, uap) 799 struct thread *td; 800 register struct ocreat_args /* { 801 char *path; 802 int mode; 803 } */ *uap; 804 { 805 struct open_args /* { 806 char *path; 807 int flags; 808 int mode; 809 } */ nuap; 810 811 nuap.path = uap->path; 812 nuap.mode = uap->mode; 813 nuap.flags = O_WRONLY | O_CREAT | O_TRUNC; 814 return (open(td, &nuap)); 815 } 816 #endif /* COMPAT_43 */ 817 818 /* 819 * Create a special file. 820 */ 821 #ifndef _SYS_SYSPROTO_H_ 822 struct mknod_args { 823 char *path; 824 int mode; 825 int dev; 826 }; 827 #endif 828 /* ARGSUSED */ 829 int 830 mknod(td, uap) 831 struct thread *td; 832 register struct mknod_args /* { 833 char *path; 834 int mode; 835 int dev; 836 } */ *uap; 837 { 838 839 return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); 840 } 841 842 int 843 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, 844 int dev) 845 { 846 struct vnode *vp; 847 struct mount *mp; 848 struct vattr vattr; 849 int error; 850 int whiteout = 0; 851 struct nameidata nd; 852 853 switch (mode & S_IFMT) { 854 case S_IFCHR: 855 case S_IFBLK: 856 error = suser(td); 857 break; 858 default: 859 error = suser_cred(td->td_ucred, PRISON_ROOT); 860 break; 861 } 862 if (error) 863 return (error); 864 restart: 865 bwillwrite(); 866 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, pathseg, path, td); 867 if ((error = namei(&nd)) != 0) 868 return (error); 869 vp = nd.ni_vp; 870 if (vp != NULL) { 871 vrele(vp); 872 error = EEXIST; 873 } else { 874 VATTR_NULL(&vattr); 875 FILEDESC_LOCK(td->td_proc->p_fd); 876 vattr.va_mode = (mode & ALLPERMS) & 877 ~td->td_proc->p_fd->fd_cmask; 878 FILEDESC_UNLOCK(td->td_proc->p_fd); 879 vattr.va_rdev = dev; 880 whiteout = 0; 881 882 switch (mode & S_IFMT) { 883 case S_IFMT: /* used by badsect to flag bad sectors */ 884 vattr.va_type = VBAD; 885 break; 886 case S_IFCHR: 887 vattr.va_type = VCHR; 888 break; 889 case S_IFBLK: 890 vattr.va_type = VBLK; 891 break; 892 case S_IFWHT: 893 whiteout = 1; 894 break; 895 default: 896 error = EINVAL; 897 break; 898 } 899 } 900 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 901 NDFREE(&nd, NDF_ONLY_PNBUF); 902 vput(nd.ni_dvp); 903 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 904 return (error); 905 goto restart; 906 } 907 #ifdef MAC 908 if (error == 0 && !whiteout) 909 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, 910 &nd.ni_cnd, &vattr); 911 #endif 912 if (!error) { 913 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 914 if (whiteout) 915 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 916 else { 917 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 918 &nd.ni_cnd, &vattr); 919 if (error == 0) 920 vput(nd.ni_vp); 921 } 922 } 923 NDFREE(&nd, NDF_ONLY_PNBUF); 924 vput(nd.ni_dvp); 925 vn_finished_write(mp); 926 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); 927 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); 928 return (error); 929 } 930 931 /* 932 * Create a named pipe. 933 */ 934 #ifndef _SYS_SYSPROTO_H_ 935 struct mkfifo_args { 936 char *path; 937 int mode; 938 }; 939 #endif 940 /* ARGSUSED */ 941 int 942 mkfifo(td, uap) 943 struct thread *td; 944 register struct mkfifo_args /* { 945 char *path; 946 int mode; 947 } */ *uap; 948 { 949 950 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); 951 } 952 953 int 954 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) 955 { 956 struct mount *mp; 957 struct vattr vattr; 958 int error; 959 struct nameidata nd; 960 961 restart: 962 bwillwrite(); 963 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, pathseg, path, td); 964 if ((error = namei(&nd)) != 0) 965 return (error); 966 if (nd.ni_vp != NULL) { 967 NDFREE(&nd, NDF_ONLY_PNBUF); 968 vrele(nd.ni_vp); 969 vput(nd.ni_dvp); 970 return (EEXIST); 971 } 972 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 973 NDFREE(&nd, NDF_ONLY_PNBUF); 974 vput(nd.ni_dvp); 975 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 976 return (error); 977 goto restart; 978 } 979 VATTR_NULL(&vattr); 980 vattr.va_type = VFIFO; 981 FILEDESC_LOCK(td->td_proc->p_fd); 982 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; 983 FILEDESC_UNLOCK(td->td_proc->p_fd); 984 #ifdef MAC 985 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 986 &vattr); 987 if (error) 988 goto out; 989 #endif 990 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 991 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 992 if (error == 0) 993 vput(nd.ni_vp); 994 #ifdef MAC 995 out: 996 #endif 997 NDFREE(&nd, NDF_ONLY_PNBUF); 998 vput(nd.ni_dvp); 999 vn_finished_write(mp); 1000 return (error); 1001 } 1002 1003 /* 1004 * Make a hard file link. 1005 */ 1006 #ifndef _SYS_SYSPROTO_H_ 1007 struct link_args { 1008 char *path; 1009 char *link; 1010 }; 1011 #endif 1012 /* ARGSUSED */ 1013 int 1014 link(td, uap) 1015 struct thread *td; 1016 register struct link_args /* { 1017 char *path; 1018 char *link; 1019 } */ *uap; 1020 { 1021 1022 return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); 1023 } 1024 1025 int 1026 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) 1027 { 1028 struct vnode *vp; 1029 struct mount *mp; 1030 struct nameidata nd; 1031 int error; 1032 1033 bwillwrite(); 1034 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, segflg, path, td); 1035 if ((error = namei(&nd)) != 0) 1036 return (error); 1037 NDFREE(&nd, NDF_ONLY_PNBUF); 1038 vp = nd.ni_vp; 1039 if (vp->v_type == VDIR) { 1040 vrele(vp); 1041 return (EPERM); /* POSIX */ 1042 } 1043 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 1044 vrele(vp); 1045 return (error); 1046 } 1047 NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, segflg, link, td); 1048 if ((error = namei(&nd)) == 0) { 1049 if (nd.ni_vp != NULL) { 1050 vrele(nd.ni_vp); 1051 error = EEXIST; 1052 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td)) 1053 == 0) { 1054 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1055 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 1056 #ifdef MAC 1057 error = mac_check_vnode_link(td->td_ucred, nd.ni_dvp, 1058 vp, &nd.ni_cnd); 1059 if (error == 0) 1060 #endif 1061 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1062 VOP_UNLOCK(vp, 0, td); 1063 } 1064 NDFREE(&nd, NDF_ONLY_PNBUF); 1065 vput(nd.ni_dvp); 1066 } 1067 vrele(vp); 1068 vn_finished_write(mp); 1069 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); 1070 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); 1071 return (error); 1072 } 1073 1074 /* 1075 * Make a symbolic link. 1076 */ 1077 #ifndef _SYS_SYSPROTO_H_ 1078 struct symlink_args { 1079 char *path; 1080 char *link; 1081 }; 1082 #endif 1083 /* ARGSUSED */ 1084 int 1085 symlink(td, uap) 1086 struct thread *td; 1087 register struct symlink_args /* { 1088 char *path; 1089 char *link; 1090 } */ *uap; 1091 { 1092 1093 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); 1094 } 1095 1096 int 1097 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) 1098 { 1099 struct mount *mp; 1100 struct vattr vattr; 1101 char *syspath; 1102 int error; 1103 struct nameidata nd; 1104 1105 if (segflg == UIO_SYSSPACE) { 1106 syspath = path; 1107 } else { 1108 syspath = uma_zalloc(namei_zone, M_WAITOK); 1109 if ((error = copyinstr(path, syspath, MAXPATHLEN, NULL)) != 0) 1110 goto out; 1111 } 1112 restart: 1113 bwillwrite(); 1114 NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, segflg, link, td); 1115 if ((error = namei(&nd)) != 0) 1116 goto out; 1117 if (nd.ni_vp) { 1118 NDFREE(&nd, NDF_ONLY_PNBUF); 1119 vrele(nd.ni_vp); 1120 vput(nd.ni_dvp); 1121 error = EEXIST; 1122 goto out; 1123 } 1124 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1125 NDFREE(&nd, NDF_ONLY_PNBUF); 1126 vput(nd.ni_dvp); 1127 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1128 return (error); 1129 goto restart; 1130 } 1131 VATTR_NULL(&vattr); 1132 FILEDESC_LOCK(td->td_proc->p_fd); 1133 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; 1134 FILEDESC_UNLOCK(td->td_proc->p_fd); 1135 #ifdef MAC 1136 vattr.va_type = VLNK; 1137 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1138 &vattr); 1139 if (error) 1140 goto out2; 1141 #endif 1142 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1143 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); 1144 if (error == 0) 1145 vput(nd.ni_vp); 1146 #ifdef MAC 1147 out2: 1148 #endif 1149 NDFREE(&nd, NDF_ONLY_PNBUF); 1150 vput(nd.ni_dvp); 1151 vn_finished_write(mp); 1152 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); 1153 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); 1154 out: 1155 if (segflg != UIO_SYSSPACE) 1156 uma_zfree(namei_zone, syspath); 1157 return (error); 1158 } 1159 1160 /* 1161 * Delete a whiteout from the filesystem. 1162 */ 1163 /* ARGSUSED */ 1164 int 1165 undelete(td, uap) 1166 struct thread *td; 1167 register struct undelete_args /* { 1168 char *path; 1169 } */ *uap; 1170 { 1171 int error; 1172 struct mount *mp; 1173 struct nameidata nd; 1174 1175 restart: 1176 bwillwrite(); 1177 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE, 1178 uap->path, td); 1179 error = namei(&nd); 1180 if (error) 1181 return (error); 1182 1183 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1184 NDFREE(&nd, NDF_ONLY_PNBUF); 1185 if (nd.ni_vp) 1186 vrele(nd.ni_vp); 1187 vput(nd.ni_dvp); 1188 return (EEXIST); 1189 } 1190 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1191 NDFREE(&nd, NDF_ONLY_PNBUF); 1192 vput(nd.ni_dvp); 1193 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1194 return (error); 1195 goto restart; 1196 } 1197 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1198 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); 1199 NDFREE(&nd, NDF_ONLY_PNBUF); 1200 vput(nd.ni_dvp); 1201 vn_finished_write(mp); 1202 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); 1203 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); 1204 return (error); 1205 } 1206 1207 /* 1208 * Delete a name from the filesystem. 1209 */ 1210 #ifndef _SYS_SYSPROTO_H_ 1211 struct unlink_args { 1212 char *path; 1213 }; 1214 #endif 1215 /* ARGSUSED */ 1216 int 1217 unlink(td, uap) 1218 struct thread *td; 1219 struct unlink_args /* { 1220 char *path; 1221 } */ *uap; 1222 { 1223 1224 return (kern_unlink(td, uap->path, UIO_USERSPACE)); 1225 } 1226 1227 int 1228 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) 1229 { 1230 struct mount *mp; 1231 struct vnode *vp; 1232 int error; 1233 struct nameidata nd; 1234 1235 restart: 1236 bwillwrite(); 1237 NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, pathseg, path, td); 1238 if ((error = namei(&nd)) != 0) 1239 return (error); 1240 vp = nd.ni_vp; 1241 if (vp->v_type == VDIR) 1242 error = EPERM; /* POSIX */ 1243 else { 1244 /* 1245 * The root of a mounted filesystem cannot be deleted. 1246 * 1247 * XXX: can this only be a VDIR case? 1248 */ 1249 if (vp->v_vflag & VV_ROOT) 1250 error = EBUSY; 1251 } 1252 if (error == 0) { 1253 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1254 NDFREE(&nd, NDF_ONLY_PNBUF); 1255 if (vp == nd.ni_dvp) 1256 vrele(vp); 1257 else 1258 vput(vp); 1259 vput(nd.ni_dvp); 1260 if ((error = vn_start_write(NULL, &mp, 1261 V_XSLEEP | PCATCH)) != 0) 1262 return (error); 1263 goto restart; 1264 } 1265 #ifdef MAC 1266 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, 1267 &nd.ni_cnd); 1268 if (error) 1269 goto out; 1270 #endif 1271 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1272 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1273 #ifdef MAC 1274 out: 1275 #endif 1276 vn_finished_write(mp); 1277 } 1278 NDFREE(&nd, NDF_ONLY_PNBUF); 1279 if (vp == nd.ni_dvp) 1280 vrele(vp); 1281 else 1282 vput(vp); 1283 vput(nd.ni_dvp); 1284 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); 1285 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); 1286 return (error); 1287 } 1288 1289 /* 1290 * Reposition read/write file offset. 1291 */ 1292 #ifndef _SYS_SYSPROTO_H_ 1293 struct lseek_args { 1294 int fd; 1295 int pad; 1296 off_t offset; 1297 int whence; 1298 }; 1299 #endif 1300 int 1301 lseek(td, uap) 1302 struct thread *td; 1303 register struct lseek_args /* { 1304 int fd; 1305 int pad; 1306 off_t offset; 1307 int whence; 1308 } */ *uap; 1309 { 1310 struct ucred *cred = td->td_ucred; 1311 struct file *fp; 1312 struct vnode *vp; 1313 struct vattr vattr; 1314 off_t offset; 1315 int error, noneg; 1316 1317 if ((error = fget(td, uap->fd, &fp)) != 0) 1318 return (error); 1319 if (fp->f_type != DTYPE_VNODE) { 1320 fdrop(fp, td); 1321 return (ESPIPE); 1322 } 1323 vp = fp->f_data; 1324 noneg = (vp->v_type != VCHR); 1325 offset = uap->offset; 1326 switch (uap->whence) { 1327 case L_INCR: 1328 if (noneg && 1329 (fp->f_offset < 0 || 1330 (offset > 0 && fp->f_offset > OFF_MAX - offset))) { 1331 error = EOVERFLOW; 1332 break; 1333 } 1334 offset += fp->f_offset; 1335 break; 1336 case L_XTND: 1337 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1338 error = VOP_GETATTR(vp, &vattr, cred, td); 1339 VOP_UNLOCK(vp, 0, td); 1340 if (error) 1341 break; 1342 if (noneg && 1343 (vattr.va_size > OFF_MAX || 1344 (offset > 0 && vattr.va_size > OFF_MAX - offset))) { 1345 error = EOVERFLOW; 1346 break; 1347 } 1348 offset += vattr.va_size; 1349 break; 1350 case L_SET: 1351 break; 1352 default: 1353 error = EINVAL; 1354 } 1355 if (error == 0 && noneg && offset < 0) 1356 error = EINVAL; 1357 if (error != 0) { 1358 fdrop(fp, td); 1359 return (error); 1360 } 1361 fp->f_offset = offset; 1362 *(off_t *)(td->td_retval) = fp->f_offset; 1363 fdrop(fp, td); 1364 return (0); 1365 } 1366 1367 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1368 /* 1369 * Reposition read/write file offset. 1370 */ 1371 #ifndef _SYS_SYSPROTO_H_ 1372 struct olseek_args { 1373 int fd; 1374 long offset; 1375 int whence; 1376 }; 1377 #endif 1378 int 1379 olseek(td, uap) 1380 struct thread *td; 1381 register struct olseek_args /* { 1382 int fd; 1383 long offset; 1384 int whence; 1385 } */ *uap; 1386 { 1387 struct lseek_args /* { 1388 int fd; 1389 int pad; 1390 off_t offset; 1391 int whence; 1392 } */ nuap; 1393 int error; 1394 1395 nuap.fd = uap->fd; 1396 nuap.offset = uap->offset; 1397 nuap.whence = uap->whence; 1398 error = lseek(td, &nuap); 1399 return (error); 1400 } 1401 #endif /* COMPAT_43 */ 1402 1403 /* 1404 * Check access permissions using passed credentials. 1405 */ 1406 static int 1407 vn_access(vp, user_flags, cred, td) 1408 struct vnode *vp; 1409 int user_flags; 1410 struct ucred *cred; 1411 struct thread *td; 1412 { 1413 int error, flags; 1414 1415 /* Flags == 0 means only check for existence. */ 1416 error = 0; 1417 if (user_flags) { 1418 flags = 0; 1419 if (user_flags & R_OK) 1420 flags |= VREAD; 1421 if (user_flags & W_OK) 1422 flags |= VWRITE; 1423 if (user_flags & X_OK) 1424 flags |= VEXEC; 1425 #ifdef MAC 1426 error = mac_check_vnode_access(cred, vp, flags); 1427 if (error) 1428 return (error); 1429 #endif 1430 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 1431 error = VOP_ACCESS(vp, flags, cred, td); 1432 } 1433 return (error); 1434 } 1435 1436 /* 1437 * Check access permissions using "real" credentials. 1438 */ 1439 #ifndef _SYS_SYSPROTO_H_ 1440 struct access_args { 1441 char *path; 1442 int flags; 1443 }; 1444 #endif 1445 int 1446 access(td, uap) 1447 struct thread *td; 1448 register struct access_args /* { 1449 char *path; 1450 int flags; 1451 } */ *uap; 1452 { 1453 1454 return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags)); 1455 } 1456 1457 int 1458 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags) 1459 { 1460 struct ucred *cred, *tmpcred; 1461 register struct vnode *vp; 1462 int error; 1463 struct nameidata nd; 1464 1465 /* 1466 * Create and modify a temporary credential instead of one that 1467 * is potentially shared. This could also mess up socket 1468 * buffer accounting which can run in an interrupt context. 1469 * 1470 * XXX - Depending on how "threads" are finally implemented, it 1471 * may be better to explicitly pass the credential to namei() 1472 * rather than to modify the potentially shared process structure. 1473 */ 1474 cred = td->td_ucred; 1475 tmpcred = crdup(cred); 1476 tmpcred->cr_uid = cred->cr_ruid; 1477 tmpcred->cr_groups[0] = cred->cr_rgid; 1478 td->td_ucred = tmpcred; 1479 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, pathseg, path, td); 1480 if ((error = namei(&nd)) != 0) 1481 goto out1; 1482 vp = nd.ni_vp; 1483 1484 error = vn_access(vp, flags, tmpcred, td); 1485 NDFREE(&nd, NDF_ONLY_PNBUF); 1486 vput(vp); 1487 out1: 1488 td->td_ucred = cred; 1489 crfree(tmpcred); 1490 return (error); 1491 } 1492 1493 /* 1494 * Check access permissions using "effective" credentials. 1495 */ 1496 #ifndef _SYS_SYSPROTO_H_ 1497 struct eaccess_args { 1498 char *path; 1499 int flags; 1500 }; 1501 #endif 1502 int 1503 eaccess(td, uap) 1504 struct thread *td; 1505 register struct eaccess_args /* { 1506 char *path; 1507 int flags; 1508 } */ *uap; 1509 { 1510 struct nameidata nd; 1511 struct vnode *vp; 1512 int error; 1513 1514 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1515 uap->path, td); 1516 if ((error = namei(&nd)) != 0) 1517 return (error); 1518 vp = nd.ni_vp; 1519 1520 error = vn_access(vp, uap->flags, td->td_ucred, td); 1521 NDFREE(&nd, NDF_ONLY_PNBUF); 1522 vput(vp); 1523 return (error); 1524 } 1525 1526 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1527 /* 1528 * Get file status; this version follows links. 1529 */ 1530 #ifndef _SYS_SYSPROTO_H_ 1531 struct ostat_args { 1532 char *path; 1533 struct ostat *ub; 1534 }; 1535 #endif 1536 /* ARGSUSED */ 1537 int 1538 ostat(td, uap) 1539 struct thread *td; 1540 register struct ostat_args /* { 1541 char *path; 1542 struct ostat *ub; 1543 } */ *uap; 1544 { 1545 struct stat sb; 1546 struct ostat osb; 1547 int error; 1548 struct nameidata nd; 1549 1550 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1551 uap->path, td); 1552 if ((error = namei(&nd)) != 0) 1553 return (error); 1554 NDFREE(&nd, NDF_ONLY_PNBUF); 1555 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1556 vput(nd.ni_vp); 1557 if (error) 1558 return (error); 1559 cvtstat(&sb, &osb); 1560 error = copyout(&osb, uap->ub, sizeof (osb)); 1561 return (error); 1562 } 1563 1564 /* 1565 * Get file status; this version does not follow links. 1566 */ 1567 #ifndef _SYS_SYSPROTO_H_ 1568 struct olstat_args { 1569 char *path; 1570 struct ostat *ub; 1571 }; 1572 #endif 1573 /* ARGSUSED */ 1574 int 1575 olstat(td, uap) 1576 struct thread *td; 1577 register struct olstat_args /* { 1578 char *path; 1579 struct ostat *ub; 1580 } */ *uap; 1581 { 1582 struct vnode *vp; 1583 struct stat sb; 1584 struct ostat osb; 1585 int error; 1586 struct nameidata nd; 1587 1588 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1589 uap->path, td); 1590 if ((error = namei(&nd)) != 0) 1591 return (error); 1592 vp = nd.ni_vp; 1593 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1594 NDFREE(&nd, NDF_ONLY_PNBUF); 1595 vput(vp); 1596 if (error) 1597 return (error); 1598 cvtstat(&sb, &osb); 1599 error = copyout(&osb, uap->ub, sizeof (osb)); 1600 return (error); 1601 } 1602 1603 /* 1604 * Convert from an old to a new stat structure. 1605 */ 1606 void 1607 cvtstat(st, ost) 1608 struct stat *st; 1609 struct ostat *ost; 1610 { 1611 1612 ost->st_dev = st->st_dev; 1613 ost->st_ino = st->st_ino; 1614 ost->st_mode = st->st_mode; 1615 ost->st_nlink = st->st_nlink; 1616 ost->st_uid = st->st_uid; 1617 ost->st_gid = st->st_gid; 1618 ost->st_rdev = st->st_rdev; 1619 if (st->st_size < (quad_t)1 << 32) 1620 ost->st_size = st->st_size; 1621 else 1622 ost->st_size = -2; 1623 ost->st_atime = st->st_atime; 1624 ost->st_mtime = st->st_mtime; 1625 ost->st_ctime = st->st_ctime; 1626 ost->st_blksize = st->st_blksize; 1627 ost->st_blocks = st->st_blocks; 1628 ost->st_flags = st->st_flags; 1629 ost->st_gen = st->st_gen; 1630 } 1631 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1632 1633 /* 1634 * Get file status; this version follows links. 1635 */ 1636 #ifndef _SYS_SYSPROTO_H_ 1637 struct stat_args { 1638 char *path; 1639 struct stat *ub; 1640 }; 1641 #endif 1642 /* ARGSUSED */ 1643 int 1644 stat(td, uap) 1645 struct thread *td; 1646 register struct stat_args /* { 1647 char *path; 1648 struct stat *ub; 1649 } */ *uap; 1650 { 1651 struct stat sb; 1652 int error; 1653 struct nameidata nd; 1654 1655 #ifdef LOOKUP_SHARED 1656 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ, 1657 UIO_USERSPACE, uap->path, td); 1658 #else 1659 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1660 uap->path, td); 1661 #endif 1662 if ((error = namei(&nd)) != 0) 1663 return (error); 1664 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1665 NDFREE(&nd, NDF_ONLY_PNBUF); 1666 vput(nd.ni_vp); 1667 if (error) 1668 return (error); 1669 error = copyout(&sb, uap->ub, sizeof (sb)); 1670 return (error); 1671 } 1672 1673 /* 1674 * Get file status; this version does not follow links. 1675 */ 1676 #ifndef _SYS_SYSPROTO_H_ 1677 struct lstat_args { 1678 char *path; 1679 struct stat *ub; 1680 }; 1681 #endif 1682 /* ARGSUSED */ 1683 int 1684 lstat(td, uap) 1685 struct thread *td; 1686 register struct lstat_args /* { 1687 char *path; 1688 struct stat *ub; 1689 } */ *uap; 1690 { 1691 int error; 1692 struct vnode *vp; 1693 struct stat sb; 1694 struct nameidata nd; 1695 1696 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1697 uap->path, td); 1698 if ((error = namei(&nd)) != 0) 1699 return (error); 1700 vp = nd.ni_vp; 1701 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1702 NDFREE(&nd, NDF_ONLY_PNBUF); 1703 vput(vp); 1704 if (error) 1705 return (error); 1706 error = copyout(&sb, uap->ub, sizeof (sb)); 1707 return (error); 1708 } 1709 1710 /* 1711 * Implementation of the NetBSD stat() function. 1712 * XXX This should probably be collapsed with the FreeBSD version, 1713 * as the differences are only due to vn_stat() clearing spares at 1714 * the end of the structures. vn_stat could be split to avoid this, 1715 * and thus collapse the following to close to zero code. 1716 */ 1717 void 1718 cvtnstat(sb, nsb) 1719 struct stat *sb; 1720 struct nstat *nsb; 1721 { 1722 bzero(nsb, sizeof *nsb); 1723 nsb->st_dev = sb->st_dev; 1724 nsb->st_ino = sb->st_ino; 1725 nsb->st_mode = sb->st_mode; 1726 nsb->st_nlink = sb->st_nlink; 1727 nsb->st_uid = sb->st_uid; 1728 nsb->st_gid = sb->st_gid; 1729 nsb->st_rdev = sb->st_rdev; 1730 nsb->st_atimespec = sb->st_atimespec; 1731 nsb->st_mtimespec = sb->st_mtimespec; 1732 nsb->st_ctimespec = sb->st_ctimespec; 1733 nsb->st_size = sb->st_size; 1734 nsb->st_blocks = sb->st_blocks; 1735 nsb->st_blksize = sb->st_blksize; 1736 nsb->st_flags = sb->st_flags; 1737 nsb->st_gen = sb->st_gen; 1738 nsb->st_birthtimespec = sb->st_birthtimespec; 1739 } 1740 1741 #ifndef _SYS_SYSPROTO_H_ 1742 struct nstat_args { 1743 char *path; 1744 struct nstat *ub; 1745 }; 1746 #endif 1747 /* ARGSUSED */ 1748 int 1749 nstat(td, uap) 1750 struct thread *td; 1751 register struct nstat_args /* { 1752 char *path; 1753 struct nstat *ub; 1754 } */ *uap; 1755 { 1756 struct stat sb; 1757 struct nstat nsb; 1758 int error; 1759 struct nameidata nd; 1760 1761 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1762 uap->path, td); 1763 if ((error = namei(&nd)) != 0) 1764 return (error); 1765 NDFREE(&nd, NDF_ONLY_PNBUF); 1766 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1767 vput(nd.ni_vp); 1768 if (error) 1769 return (error); 1770 cvtnstat(&sb, &nsb); 1771 error = copyout(&nsb, uap->ub, sizeof (nsb)); 1772 return (error); 1773 } 1774 1775 /* 1776 * NetBSD lstat. Get file status; this version does not follow links. 1777 */ 1778 #ifndef _SYS_SYSPROTO_H_ 1779 struct lstat_args { 1780 char *path; 1781 struct stat *ub; 1782 }; 1783 #endif 1784 /* ARGSUSED */ 1785 int 1786 nlstat(td, uap) 1787 struct thread *td; 1788 register struct nlstat_args /* { 1789 char *path; 1790 struct nstat *ub; 1791 } */ *uap; 1792 { 1793 int error; 1794 struct vnode *vp; 1795 struct stat sb; 1796 struct nstat nsb; 1797 struct nameidata nd; 1798 1799 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1800 uap->path, td); 1801 if ((error = namei(&nd)) != 0) 1802 return (error); 1803 vp = nd.ni_vp; 1804 NDFREE(&nd, NDF_ONLY_PNBUF); 1805 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1806 vput(vp); 1807 if (error) 1808 return (error); 1809 cvtnstat(&sb, &nsb); 1810 error = copyout(&nsb, uap->ub, sizeof (nsb)); 1811 return (error); 1812 } 1813 1814 /* 1815 * Get configurable pathname variables. 1816 */ 1817 #ifndef _SYS_SYSPROTO_H_ 1818 struct pathconf_args { 1819 char *path; 1820 int name; 1821 }; 1822 #endif 1823 /* ARGSUSED */ 1824 int 1825 pathconf(td, uap) 1826 struct thread *td; 1827 register struct pathconf_args /* { 1828 char *path; 1829 int name; 1830 } */ *uap; 1831 { 1832 int error; 1833 struct nameidata nd; 1834 1835 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1836 uap->path, td); 1837 if ((error = namei(&nd)) != 0) 1838 return (error); 1839 NDFREE(&nd, NDF_ONLY_PNBUF); 1840 1841 /* If asynchronous I/O is available, it works for all files. */ 1842 if (uap->name == _PC_ASYNC_IO) 1843 td->td_retval[0] = async_io_version; 1844 else 1845 error = VOP_PATHCONF(nd.ni_vp, uap->name, td->td_retval); 1846 vput(nd.ni_vp); 1847 return (error); 1848 } 1849 1850 /* 1851 * Return target name of a symbolic link. 1852 */ 1853 #ifndef _SYS_SYSPROTO_H_ 1854 struct readlink_args { 1855 char *path; 1856 char *buf; 1857 int count; 1858 }; 1859 #endif 1860 /* ARGSUSED */ 1861 int 1862 readlink(td, uap) 1863 struct thread *td; 1864 register struct readlink_args /* { 1865 char *path; 1866 char *buf; 1867 int count; 1868 } */ *uap; 1869 { 1870 1871 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, 1872 UIO_USERSPACE, uap->count)); 1873 } 1874 1875 int 1876 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, 1877 enum uio_seg bufseg, int count) 1878 { 1879 register struct vnode *vp; 1880 struct iovec aiov; 1881 struct uio auio; 1882 int error; 1883 struct nameidata nd; 1884 1885 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, pathseg, path, td); 1886 if ((error = namei(&nd)) != 0) 1887 return (error); 1888 NDFREE(&nd, NDF_ONLY_PNBUF); 1889 vp = nd.ni_vp; 1890 #ifdef MAC 1891 error = mac_check_vnode_readlink(td->td_ucred, vp); 1892 if (error) { 1893 vput(vp); 1894 return (error); 1895 } 1896 #endif 1897 if (vp->v_type != VLNK) 1898 error = EINVAL; 1899 else { 1900 aiov.iov_base = buf; 1901 aiov.iov_len = count; 1902 auio.uio_iov = &aiov; 1903 auio.uio_iovcnt = 1; 1904 auio.uio_offset = 0; 1905 auio.uio_rw = UIO_READ; 1906 auio.uio_segflg = bufseg; 1907 auio.uio_td = td; 1908 auio.uio_resid = count; 1909 error = VOP_READLINK(vp, &auio, td->td_ucred); 1910 } 1911 vput(vp); 1912 td->td_retval[0] = count - auio.uio_resid; 1913 return (error); 1914 } 1915 1916 /* 1917 * Common implementation code for chflags() and fchflags(). 1918 */ 1919 static int 1920 setfflags(td, vp, flags) 1921 struct thread *td; 1922 struct vnode *vp; 1923 int flags; 1924 { 1925 int error; 1926 struct mount *mp; 1927 struct vattr vattr; 1928 1929 /* 1930 * Prevent non-root users from setting flags on devices. When 1931 * a device is reused, users can retain ownership of the device 1932 * if they are allowed to set flags and programs assume that 1933 * chown can't fail when done as root. 1934 */ 1935 if (vp->v_type == VCHR || vp->v_type == VBLK) { 1936 error = suser_cred(td->td_ucred, PRISON_ROOT); 1937 if (error) 1938 return (error); 1939 } 1940 1941 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 1942 return (error); 1943 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 1944 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1945 #ifdef MAC 1946 error = mac_check_vnode_setflags(td->td_ucred, vp, vattr.va_flags); 1947 if (error == 0) { 1948 #endif 1949 VATTR_NULL(&vattr); 1950 vattr.va_flags = flags; 1951 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); 1952 #ifdef MAC 1953 } 1954 #endif 1955 VOP_UNLOCK(vp, 0, td); 1956 vn_finished_write(mp); 1957 return (error); 1958 } 1959 1960 /* 1961 * Change flags of a file given a path name. 1962 */ 1963 #ifndef _SYS_SYSPROTO_H_ 1964 struct chflags_args { 1965 char *path; 1966 int flags; 1967 }; 1968 #endif 1969 /* ARGSUSED */ 1970 int 1971 chflags(td, uap) 1972 struct thread *td; 1973 register struct chflags_args /* { 1974 char *path; 1975 int flags; 1976 } */ *uap; 1977 { 1978 int error; 1979 struct nameidata nd; 1980 1981 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 1982 if ((error = namei(&nd)) != 0) 1983 return (error); 1984 NDFREE(&nd, NDF_ONLY_PNBUF); 1985 error = setfflags(td, nd.ni_vp, uap->flags); 1986 vrele(nd.ni_vp); 1987 return error; 1988 } 1989 1990 /* 1991 * Same as chflags() but doesn't follow symlinks. 1992 */ 1993 int 1994 lchflags(td, uap) 1995 struct thread *td; 1996 register struct lchflags_args /* { 1997 char *path; 1998 int flags; 1999 } */ *uap; 2000 { 2001 int error; 2002 struct nameidata nd; 2003 2004 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td); 2005 if ((error = namei(&nd)) != 0) 2006 return (error); 2007 NDFREE(&nd, NDF_ONLY_PNBUF); 2008 error = setfflags(td, nd.ni_vp, uap->flags); 2009 vrele(nd.ni_vp); 2010 return error; 2011 } 2012 2013 /* 2014 * Change flags of a file given a file descriptor. 2015 */ 2016 #ifndef _SYS_SYSPROTO_H_ 2017 struct fchflags_args { 2018 int fd; 2019 int flags; 2020 }; 2021 #endif 2022 /* ARGSUSED */ 2023 int 2024 fchflags(td, uap) 2025 struct thread *td; 2026 register struct fchflags_args /* { 2027 int fd; 2028 int flags; 2029 } */ *uap; 2030 { 2031 struct file *fp; 2032 int error; 2033 2034 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2035 return (error); 2036 error = setfflags(td, fp->f_data, uap->flags); 2037 fdrop(fp, td); 2038 return (error); 2039 } 2040 2041 /* 2042 * Common implementation code for chmod(), lchmod() and fchmod(). 2043 */ 2044 static int 2045 setfmode(td, vp, mode) 2046 struct thread *td; 2047 struct vnode *vp; 2048 int mode; 2049 { 2050 int error; 2051 struct mount *mp; 2052 struct vattr vattr; 2053 2054 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2055 return (error); 2056 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2057 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2058 VATTR_NULL(&vattr); 2059 vattr.va_mode = mode & ALLPERMS; 2060 #ifdef MAC 2061 error = mac_check_vnode_setmode(td->td_ucred, vp, vattr.va_mode); 2062 if (error == 0) 2063 #endif 2064 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); 2065 VOP_UNLOCK(vp, 0, td); 2066 vn_finished_write(mp); 2067 return error; 2068 } 2069 2070 /* 2071 * Change mode of a file given path name. 2072 */ 2073 #ifndef _SYS_SYSPROTO_H_ 2074 struct chmod_args { 2075 char *path; 2076 int mode; 2077 }; 2078 #endif 2079 /* ARGSUSED */ 2080 int 2081 chmod(td, uap) 2082 struct thread *td; 2083 register struct chmod_args /* { 2084 char *path; 2085 int mode; 2086 } */ *uap; 2087 { 2088 2089 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); 2090 } 2091 2092 int 2093 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2094 { 2095 int error; 2096 struct nameidata nd; 2097 2098 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); 2099 if ((error = namei(&nd)) != 0) 2100 return (error); 2101 NDFREE(&nd, NDF_ONLY_PNBUF); 2102 error = setfmode(td, nd.ni_vp, mode); 2103 vrele(nd.ni_vp); 2104 return error; 2105 } 2106 2107 /* 2108 * Change mode of a file given path name (don't follow links.) 2109 */ 2110 #ifndef _SYS_SYSPROTO_H_ 2111 struct lchmod_args { 2112 char *path; 2113 int mode; 2114 }; 2115 #endif 2116 /* ARGSUSED */ 2117 int 2118 lchmod(td, uap) 2119 struct thread *td; 2120 register struct lchmod_args /* { 2121 char *path; 2122 int mode; 2123 } */ *uap; 2124 { 2125 int error; 2126 struct nameidata nd; 2127 2128 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td); 2129 if ((error = namei(&nd)) != 0) 2130 return (error); 2131 NDFREE(&nd, NDF_ONLY_PNBUF); 2132 error = setfmode(td, nd.ni_vp, uap->mode); 2133 vrele(nd.ni_vp); 2134 return error; 2135 } 2136 2137 /* 2138 * Change mode of a file given a file descriptor. 2139 */ 2140 #ifndef _SYS_SYSPROTO_H_ 2141 struct fchmod_args { 2142 int fd; 2143 int mode; 2144 }; 2145 #endif 2146 /* ARGSUSED */ 2147 int 2148 fchmod(td, uap) 2149 struct thread *td; 2150 register struct fchmod_args /* { 2151 int fd; 2152 int mode; 2153 } */ *uap; 2154 { 2155 struct file *fp; 2156 struct vnode *vp; 2157 int error; 2158 2159 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2160 return (error); 2161 vp = fp->f_data; 2162 error = setfmode(td, fp->f_data, uap->mode); 2163 fdrop(fp, td); 2164 return (error); 2165 } 2166 2167 /* 2168 * Common implementation for chown(), lchown(), and fchown() 2169 */ 2170 static int 2171 setfown(td, vp, uid, gid) 2172 struct thread *td; 2173 struct vnode *vp; 2174 uid_t uid; 2175 gid_t gid; 2176 { 2177 int error; 2178 struct mount *mp; 2179 struct vattr vattr; 2180 2181 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2182 return (error); 2183 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2184 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2185 VATTR_NULL(&vattr); 2186 vattr.va_uid = uid; 2187 vattr.va_gid = gid; 2188 #ifdef MAC 2189 error = mac_check_vnode_setowner(td->td_ucred, vp, vattr.va_uid, 2190 vattr.va_gid); 2191 if (error == 0) 2192 #endif 2193 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); 2194 VOP_UNLOCK(vp, 0, td); 2195 vn_finished_write(mp); 2196 return error; 2197 } 2198 2199 /* 2200 * Set ownership given a path name. 2201 */ 2202 #ifndef _SYS_SYSPROTO_H_ 2203 struct chown_args { 2204 char *path; 2205 int uid; 2206 int gid; 2207 }; 2208 #endif 2209 /* ARGSUSED */ 2210 int 2211 chown(td, uap) 2212 struct thread *td; 2213 register struct chown_args /* { 2214 char *path; 2215 int uid; 2216 int gid; 2217 } */ *uap; 2218 { 2219 2220 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 2221 } 2222 2223 int 2224 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 2225 int gid) 2226 { 2227 int error; 2228 struct nameidata nd; 2229 2230 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); 2231 if ((error = namei(&nd)) != 0) 2232 return (error); 2233 NDFREE(&nd, NDF_ONLY_PNBUF); 2234 error = setfown(td, nd.ni_vp, uid, gid); 2235 vrele(nd.ni_vp); 2236 return (error); 2237 } 2238 2239 /* 2240 * Set ownership given a path name, do not cross symlinks. 2241 */ 2242 #ifndef _SYS_SYSPROTO_H_ 2243 struct lchown_args { 2244 char *path; 2245 int uid; 2246 int gid; 2247 }; 2248 #endif 2249 /* ARGSUSED */ 2250 int 2251 lchown(td, uap) 2252 struct thread *td; 2253 register struct lchown_args /* { 2254 char *path; 2255 int uid; 2256 int gid; 2257 } */ *uap; 2258 { 2259 2260 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 2261 } 2262 2263 int 2264 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 2265 int gid) 2266 { 2267 int error; 2268 struct nameidata nd; 2269 2270 NDINIT(&nd, LOOKUP, NOFOLLOW, pathseg, path, td); 2271 if ((error = namei(&nd)) != 0) 2272 return (error); 2273 NDFREE(&nd, NDF_ONLY_PNBUF); 2274 error = setfown(td, nd.ni_vp, uid, gid); 2275 vrele(nd.ni_vp); 2276 return (error); 2277 } 2278 2279 /* 2280 * Set ownership given a file descriptor. 2281 */ 2282 #ifndef _SYS_SYSPROTO_H_ 2283 struct fchown_args { 2284 int fd; 2285 int uid; 2286 int gid; 2287 }; 2288 #endif 2289 /* ARGSUSED */ 2290 int 2291 fchown(td, uap) 2292 struct thread *td; 2293 register struct fchown_args /* { 2294 int fd; 2295 int uid; 2296 int gid; 2297 } */ *uap; 2298 { 2299 struct file *fp; 2300 struct vnode *vp; 2301 int error; 2302 2303 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2304 return (error); 2305 vp = fp->f_data; 2306 error = setfown(td, fp->f_data, uap->uid, uap->gid); 2307 fdrop(fp, td); 2308 return (error); 2309 } 2310 2311 /* 2312 * Common implementation code for utimes(), lutimes(), and futimes(). 2313 */ 2314 static int 2315 getutimes(usrtvp, tvpseg, tsp) 2316 const struct timeval *usrtvp; 2317 enum uio_seg tvpseg; 2318 struct timespec *tsp; 2319 { 2320 struct timeval tv[2]; 2321 const struct timeval *tvp; 2322 int error; 2323 2324 if (usrtvp == NULL) { 2325 microtime(&tv[0]); 2326 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2327 tsp[1] = tsp[0]; 2328 } else { 2329 if (tvpseg == UIO_SYSSPACE) { 2330 tvp = usrtvp; 2331 } else { 2332 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) 2333 return (error); 2334 tvp = tv; 2335 } 2336 2337 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 2338 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 2339 } 2340 return 0; 2341 } 2342 2343 /* 2344 * Common implementation code for utimes(), lutimes(), and futimes(). 2345 */ 2346 static int 2347 setutimes(td, vp, ts, numtimes, nullflag) 2348 struct thread *td; 2349 struct vnode *vp; 2350 const struct timespec *ts; 2351 int numtimes; 2352 int nullflag; 2353 { 2354 int error, setbirthtime; 2355 struct mount *mp; 2356 struct vattr vattr; 2357 2358 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2359 return (error); 2360 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2361 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2362 setbirthtime = 0; 2363 if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 && 2364 timespeccmp(&ts[1], &vattr.va_birthtime, < )) 2365 setbirthtime = 1; 2366 VATTR_NULL(&vattr); 2367 vattr.va_atime = ts[0]; 2368 vattr.va_mtime = ts[1]; 2369 if (setbirthtime) 2370 vattr.va_birthtime = ts[1]; 2371 if (numtimes > 2) 2372 vattr.va_birthtime = ts[2]; 2373 if (nullflag) 2374 vattr.va_vaflags |= VA_UTIMES_NULL; 2375 #ifdef MAC 2376 error = mac_check_vnode_setutimes(td->td_ucred, vp, vattr.va_atime, 2377 vattr.va_mtime); 2378 #endif 2379 if (error == 0) 2380 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); 2381 VOP_UNLOCK(vp, 0, td); 2382 vn_finished_write(mp); 2383 return error; 2384 } 2385 2386 /* 2387 * Set the access and modification times of a file. 2388 */ 2389 #ifndef _SYS_SYSPROTO_H_ 2390 struct utimes_args { 2391 char *path; 2392 struct timeval *tptr; 2393 }; 2394 #endif 2395 /* ARGSUSED */ 2396 int 2397 utimes(td, uap) 2398 struct thread *td; 2399 register struct utimes_args /* { 2400 char *path; 2401 struct timeval *tptr; 2402 } */ *uap; 2403 { 2404 2405 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, 2406 UIO_USERSPACE)); 2407 } 2408 2409 int 2410 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, 2411 struct timeval *tptr, enum uio_seg tptrseg) 2412 { 2413 struct timespec ts[2]; 2414 int error; 2415 struct nameidata nd; 2416 2417 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 2418 return (error); 2419 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); 2420 if ((error = namei(&nd)) != 0) 2421 return (error); 2422 NDFREE(&nd, NDF_ONLY_PNBUF); 2423 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 2424 vrele(nd.ni_vp); 2425 return (error); 2426 } 2427 2428 /* 2429 * Set the access and modification times of a file. 2430 */ 2431 #ifndef _SYS_SYSPROTO_H_ 2432 struct lutimes_args { 2433 char *path; 2434 struct timeval *tptr; 2435 }; 2436 #endif 2437 /* ARGSUSED */ 2438 int 2439 lutimes(td, uap) 2440 struct thread *td; 2441 register struct lutimes_args /* { 2442 char *path; 2443 struct timeval *tptr; 2444 } */ *uap; 2445 { 2446 2447 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, 2448 UIO_USERSPACE)); 2449 } 2450 2451 int 2452 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, 2453 struct timeval *tptr, enum uio_seg tptrseg) 2454 { 2455 struct timespec ts[2]; 2456 int error; 2457 struct nameidata nd; 2458 2459 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 2460 return (error); 2461 NDINIT(&nd, LOOKUP, NOFOLLOW, pathseg, path, td); 2462 if ((error = namei(&nd)) != 0) 2463 return (error); 2464 NDFREE(&nd, NDF_ONLY_PNBUF); 2465 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 2466 vrele(nd.ni_vp); 2467 return (error); 2468 } 2469 2470 /* 2471 * Set the access and modification times of a file. 2472 */ 2473 #ifndef _SYS_SYSPROTO_H_ 2474 struct futimes_args { 2475 int fd; 2476 struct timeval *tptr; 2477 }; 2478 #endif 2479 /* ARGSUSED */ 2480 int 2481 futimes(td, uap) 2482 struct thread *td; 2483 register struct futimes_args /* { 2484 int fd; 2485 struct timeval *tptr; 2486 } */ *uap; 2487 { 2488 2489 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); 2490 } 2491 2492 int 2493 kern_futimes(struct thread *td, int fd, struct timeval *tptr, 2494 enum uio_seg tptrseg) 2495 { 2496 struct timespec ts[2]; 2497 struct file *fp; 2498 int error; 2499 2500 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 2501 return (error); 2502 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 2503 return (error); 2504 error = setutimes(td, fp->f_data, ts, 2, tptr == NULL); 2505 fdrop(fp, td); 2506 return (error); 2507 } 2508 2509 /* 2510 * Truncate a file given its path name. 2511 */ 2512 #ifndef _SYS_SYSPROTO_H_ 2513 struct truncate_args { 2514 char *path; 2515 int pad; 2516 off_t length; 2517 }; 2518 #endif 2519 /* ARGSUSED */ 2520 int 2521 truncate(td, uap) 2522 struct thread *td; 2523 register struct truncate_args /* { 2524 char *path; 2525 int pad; 2526 off_t length; 2527 } */ *uap; 2528 { 2529 2530 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); 2531 } 2532 2533 int 2534 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) 2535 { 2536 struct mount *mp; 2537 struct vnode *vp; 2538 struct vattr vattr; 2539 int error; 2540 struct nameidata nd; 2541 2542 if (length < 0) 2543 return(EINVAL); 2544 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); 2545 if ((error = namei(&nd)) != 0) 2546 return (error); 2547 vp = nd.ni_vp; 2548 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 2549 vrele(vp); 2550 return (error); 2551 } 2552 NDFREE(&nd, NDF_ONLY_PNBUF); 2553 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2554 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2555 if (vp->v_type == VDIR) 2556 error = EISDIR; 2557 #ifdef MAC 2558 else if ((error = mac_check_vnode_write(td->td_ucred, NOCRED, vp))) { 2559 } 2560 #endif 2561 else if ((error = vn_writechk(vp)) == 0 && 2562 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { 2563 VATTR_NULL(&vattr); 2564 vattr.va_size = length; 2565 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); 2566 } 2567 vput(vp); 2568 vn_finished_write(mp); 2569 return (error); 2570 } 2571 2572 /* 2573 * Truncate a file given a file descriptor. 2574 */ 2575 #ifndef _SYS_SYSPROTO_H_ 2576 struct ftruncate_args { 2577 int fd; 2578 int pad; 2579 off_t length; 2580 }; 2581 #endif 2582 /* ARGSUSED */ 2583 int 2584 ftruncate(td, uap) 2585 struct thread *td; 2586 register struct ftruncate_args /* { 2587 int fd; 2588 int pad; 2589 off_t length; 2590 } */ *uap; 2591 { 2592 struct mount *mp; 2593 struct vattr vattr; 2594 struct vnode *vp; 2595 struct file *fp; 2596 int error; 2597 2598 if (uap->length < 0) 2599 return(EINVAL); 2600 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2601 return (error); 2602 if ((fp->f_flag & FWRITE) == 0) { 2603 fdrop(fp, td); 2604 return (EINVAL); 2605 } 2606 vp = fp->f_data; 2607 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 2608 fdrop(fp, td); 2609 return (error); 2610 } 2611 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2612 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2613 if (vp->v_type == VDIR) 2614 error = EISDIR; 2615 #ifdef MAC 2616 else if ((error = mac_check_vnode_write(td->td_ucred, fp->f_cred, 2617 vp))) { 2618 } 2619 #endif 2620 else if ((error = vn_writechk(vp)) == 0) { 2621 VATTR_NULL(&vattr); 2622 vattr.va_size = uap->length; 2623 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td); 2624 } 2625 VOP_UNLOCK(vp, 0, td); 2626 vn_finished_write(mp); 2627 fdrop(fp, td); 2628 return (error); 2629 } 2630 2631 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 2632 /* 2633 * Truncate a file given its path name. 2634 */ 2635 #ifndef _SYS_SYSPROTO_H_ 2636 struct otruncate_args { 2637 char *path; 2638 long length; 2639 }; 2640 #endif 2641 /* ARGSUSED */ 2642 int 2643 otruncate(td, uap) 2644 struct thread *td; 2645 register struct otruncate_args /* { 2646 char *path; 2647 long length; 2648 } */ *uap; 2649 { 2650 struct truncate_args /* { 2651 char *path; 2652 int pad; 2653 off_t length; 2654 } */ nuap; 2655 2656 nuap.path = uap->path; 2657 nuap.length = uap->length; 2658 return (truncate(td, &nuap)); 2659 } 2660 2661 /* 2662 * Truncate a file given a file descriptor. 2663 */ 2664 #ifndef _SYS_SYSPROTO_H_ 2665 struct oftruncate_args { 2666 int fd; 2667 long length; 2668 }; 2669 #endif 2670 /* ARGSUSED */ 2671 int 2672 oftruncate(td, uap) 2673 struct thread *td; 2674 register struct oftruncate_args /* { 2675 int fd; 2676 long length; 2677 } */ *uap; 2678 { 2679 struct ftruncate_args /* { 2680 int fd; 2681 int pad; 2682 off_t length; 2683 } */ nuap; 2684 2685 nuap.fd = uap->fd; 2686 nuap.length = uap->length; 2687 return (ftruncate(td, &nuap)); 2688 } 2689 #endif /* COMPAT_43 || COMPAT_SUNOS */ 2690 2691 /* 2692 * Sync an open file. 2693 */ 2694 #ifndef _SYS_SYSPROTO_H_ 2695 struct fsync_args { 2696 int fd; 2697 }; 2698 #endif 2699 /* ARGSUSED */ 2700 int 2701 fsync(td, uap) 2702 struct thread *td; 2703 struct fsync_args /* { 2704 int fd; 2705 } */ *uap; 2706 { 2707 struct vnode *vp; 2708 struct mount *mp; 2709 struct file *fp; 2710 vm_object_t obj; 2711 int error; 2712 2713 GIANT_REQUIRED; 2714 2715 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2716 return (error); 2717 vp = fp->f_data; 2718 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 2719 fdrop(fp, td); 2720 return (error); 2721 } 2722 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2723 if (VOP_GETVOBJECT(vp, &obj) == 0) { 2724 vm_object_page_clean(obj, 0, 0, 0); 2725 } 2726 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, td); 2727 if (error == 0 && vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) 2728 && softdep_fsync_hook != NULL) 2729 error = (*softdep_fsync_hook)(vp); 2730 2731 VOP_UNLOCK(vp, 0, td); 2732 vn_finished_write(mp); 2733 fdrop(fp, td); 2734 return (error); 2735 } 2736 2737 /* 2738 * Rename files. Source and destination must either both be directories, 2739 * or both not be directories. If target is a directory, it must be empty. 2740 */ 2741 #ifndef _SYS_SYSPROTO_H_ 2742 struct rename_args { 2743 char *from; 2744 char *to; 2745 }; 2746 #endif 2747 /* ARGSUSED */ 2748 int 2749 rename(td, uap) 2750 struct thread *td; 2751 register struct rename_args /* { 2752 char *from; 2753 char *to; 2754 } */ *uap; 2755 { 2756 2757 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); 2758 } 2759 2760 int 2761 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) 2762 { 2763 struct mount *mp = NULL; 2764 struct vnode *tvp, *fvp, *tdvp; 2765 struct nameidata fromnd, tond; 2766 int error; 2767 2768 bwillwrite(); 2769 #ifdef MAC 2770 NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART, pathseg, 2771 from, td); 2772 #else 2773 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, pathseg, from, td); 2774 #endif 2775 if ((error = namei(&fromnd)) != 0) 2776 return (error); 2777 #ifdef MAC 2778 error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp, 2779 fromnd.ni_vp, &fromnd.ni_cnd); 2780 VOP_UNLOCK(fromnd.ni_dvp, 0, td); 2781 VOP_UNLOCK(fromnd.ni_vp, 0, td); 2782 #endif 2783 fvp = fromnd.ni_vp; 2784 if (error == 0) 2785 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); 2786 if (error != 0) { 2787 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2788 vrele(fromnd.ni_dvp); 2789 vrele(fvp); 2790 goto out1; 2791 } 2792 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | 2793 NOOBJ, pathseg, to, td); 2794 if (fromnd.ni_vp->v_type == VDIR) 2795 tond.ni_cnd.cn_flags |= WILLBEDIR; 2796 if ((error = namei(&tond)) != 0) { 2797 /* Translate error code for rename("dir1", "dir2/."). */ 2798 if (error == EISDIR && fvp->v_type == VDIR) 2799 error = EINVAL; 2800 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2801 vrele(fromnd.ni_dvp); 2802 vrele(fvp); 2803 goto out1; 2804 } 2805 tdvp = tond.ni_dvp; 2806 tvp = tond.ni_vp; 2807 if (tvp != NULL) { 2808 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2809 error = ENOTDIR; 2810 goto out; 2811 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2812 error = EISDIR; 2813 goto out; 2814 } 2815 } 2816 if (fvp == tdvp) 2817 error = EINVAL; 2818 /* 2819 * If the source is the same as the destination (that is, if they 2820 * are links to the same vnode), then there is nothing to do. 2821 */ 2822 if (fvp == tvp) 2823 error = -1; 2824 #ifdef MAC 2825 else 2826 error = mac_check_vnode_rename_to(td->td_ucred, tdvp, 2827 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); 2828 #endif 2829 out: 2830 if (!error) { 2831 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); 2832 if (fromnd.ni_dvp != tdvp) { 2833 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 2834 } 2835 if (tvp) { 2836 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); 2837 } 2838 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 2839 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 2840 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2841 NDFREE(&tond, NDF_ONLY_PNBUF); 2842 } else { 2843 NDFREE(&fromnd, NDF_ONLY_PNBUF); 2844 NDFREE(&tond, NDF_ONLY_PNBUF); 2845 if (tdvp == tvp) 2846 vrele(tdvp); 2847 else 2848 vput(tdvp); 2849 if (tvp) 2850 vput(tvp); 2851 vrele(fromnd.ni_dvp); 2852 vrele(fvp); 2853 } 2854 vrele(tond.ni_startdir); 2855 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); 2856 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); 2857 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); 2858 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); 2859 out1: 2860 vn_finished_write(mp); 2861 if (fromnd.ni_startdir) 2862 vrele(fromnd.ni_startdir); 2863 if (error == -1) 2864 return (0); 2865 return (error); 2866 } 2867 2868 /* 2869 * Make a directory file. 2870 */ 2871 #ifndef _SYS_SYSPROTO_H_ 2872 struct mkdir_args { 2873 char *path; 2874 int mode; 2875 }; 2876 #endif 2877 /* ARGSUSED */ 2878 int 2879 mkdir(td, uap) 2880 struct thread *td; 2881 register struct mkdir_args /* { 2882 char *path; 2883 int mode; 2884 } */ *uap; 2885 { 2886 2887 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); 2888 } 2889 2890 int 2891 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) 2892 { 2893 struct mount *mp; 2894 struct vnode *vp; 2895 struct vattr vattr; 2896 int error; 2897 struct nameidata nd; 2898 2899 restart: 2900 bwillwrite(); 2901 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, segflg, path, td); 2902 nd.ni_cnd.cn_flags |= WILLBEDIR; 2903 if ((error = namei(&nd)) != 0) 2904 return (error); 2905 vp = nd.ni_vp; 2906 if (vp != NULL) { 2907 NDFREE(&nd, NDF_ONLY_PNBUF); 2908 vrele(vp); 2909 /* 2910 * XXX namei called with LOCKPARENT but not LOCKLEAF has 2911 * the strange behaviour of leaving the vnode unlocked 2912 * if the target is the same vnode as the parent. 2913 */ 2914 if (vp == nd.ni_dvp) 2915 vrele(nd.ni_dvp); 2916 else 2917 vput(nd.ni_dvp); 2918 return (EEXIST); 2919 } 2920 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 2921 NDFREE(&nd, NDF_ONLY_PNBUF); 2922 vput(nd.ni_dvp); 2923 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 2924 return (error); 2925 goto restart; 2926 } 2927 VATTR_NULL(&vattr); 2928 vattr.va_type = VDIR; 2929 FILEDESC_LOCK(td->td_proc->p_fd); 2930 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; 2931 FILEDESC_UNLOCK(td->td_proc->p_fd); 2932 #ifdef MAC 2933 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 2934 &vattr); 2935 if (error) 2936 goto out; 2937 #endif 2938 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 2939 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 2940 #ifdef MAC 2941 out: 2942 #endif 2943 NDFREE(&nd, NDF_ONLY_PNBUF); 2944 vput(nd.ni_dvp); 2945 if (!error) 2946 vput(nd.ni_vp); 2947 vn_finished_write(mp); 2948 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); 2949 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); 2950 return (error); 2951 } 2952 2953 /* 2954 * Remove a directory file. 2955 */ 2956 #ifndef _SYS_SYSPROTO_H_ 2957 struct rmdir_args { 2958 char *path; 2959 }; 2960 #endif 2961 /* ARGSUSED */ 2962 int 2963 rmdir(td, uap) 2964 struct thread *td; 2965 struct rmdir_args /* { 2966 char *path; 2967 } */ *uap; 2968 { 2969 2970 return (kern_rmdir(td, uap->path, UIO_USERSPACE)); 2971 } 2972 2973 int 2974 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) 2975 { 2976 struct mount *mp; 2977 struct vnode *vp; 2978 int error; 2979 struct nameidata nd; 2980 2981 restart: 2982 bwillwrite(); 2983 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, pathseg, path, td); 2984 if ((error = namei(&nd)) != 0) 2985 return (error); 2986 vp = nd.ni_vp; 2987 if (vp->v_type != VDIR) { 2988 error = ENOTDIR; 2989 goto out; 2990 } 2991 /* 2992 * No rmdir "." please. 2993 */ 2994 if (nd.ni_dvp == vp) { 2995 error = EINVAL; 2996 goto out; 2997 } 2998 /* 2999 * The root of a mounted filesystem cannot be deleted. 3000 */ 3001 if (vp->v_vflag & VV_ROOT) { 3002 error = EBUSY; 3003 goto out; 3004 } 3005 #ifdef MAC 3006 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, 3007 &nd.ni_cnd); 3008 if (error) 3009 goto out; 3010 #endif 3011 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3012 NDFREE(&nd, NDF_ONLY_PNBUF); 3013 if (nd.ni_dvp == vp) 3014 vrele(nd.ni_dvp); 3015 else 3016 vput(nd.ni_dvp); 3017 vput(vp); 3018 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3019 return (error); 3020 goto restart; 3021 } 3022 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3023 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3024 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 3025 vn_finished_write(mp); 3026 out: 3027 NDFREE(&nd, NDF_ONLY_PNBUF); 3028 if (nd.ni_dvp == vp) 3029 vrele(nd.ni_dvp); 3030 else 3031 vput(nd.ni_dvp); 3032 vput(vp); 3033 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); 3034 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); 3035 return (error); 3036 } 3037 3038 #ifdef COMPAT_43 3039 /* 3040 * Read a block of directory entries in a filesystem independent format. 3041 */ 3042 #ifndef _SYS_SYSPROTO_H_ 3043 struct ogetdirentries_args { 3044 int fd; 3045 char *buf; 3046 u_int count; 3047 long *basep; 3048 }; 3049 #endif 3050 int 3051 ogetdirentries(td, uap) 3052 struct thread *td; 3053 register struct ogetdirentries_args /* { 3054 int fd; 3055 char *buf; 3056 u_int count; 3057 long *basep; 3058 } */ *uap; 3059 { 3060 struct vnode *vp; 3061 struct file *fp; 3062 struct uio auio, kuio; 3063 struct iovec aiov, kiov; 3064 struct dirent *dp, *edp; 3065 caddr_t dirbuf; 3066 int error, eofflag, readcnt; 3067 long loff; 3068 3069 /* XXX arbitrary sanity limit on `count'. */ 3070 if (uap->count > 64 * 1024) 3071 return (EINVAL); 3072 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3073 return (error); 3074 if ((fp->f_flag & FREAD) == 0) { 3075 fdrop(fp, td); 3076 return (EBADF); 3077 } 3078 vp = fp->f_data; 3079 unionread: 3080 if (vp->v_type != VDIR) { 3081 fdrop(fp, td); 3082 return (EINVAL); 3083 } 3084 aiov.iov_base = uap->buf; 3085 aiov.iov_len = uap->count; 3086 auio.uio_iov = &aiov; 3087 auio.uio_iovcnt = 1; 3088 auio.uio_rw = UIO_READ; 3089 auio.uio_segflg = UIO_USERSPACE; 3090 auio.uio_td = td; 3091 auio.uio_resid = uap->count; 3092 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3093 loff = auio.uio_offset = fp->f_offset; 3094 #ifdef MAC 3095 error = mac_check_vnode_readdir(td->td_ucred, vp); 3096 if (error) { 3097 VOP_UNLOCK(vp, 0, td); 3098 fdrop(fp, td); 3099 return (error); 3100 } 3101 #endif 3102 # if (BYTE_ORDER != LITTLE_ENDIAN) 3103 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 3104 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 3105 NULL, NULL); 3106 fp->f_offset = auio.uio_offset; 3107 } else 3108 # endif 3109 { 3110 kuio = auio; 3111 kuio.uio_iov = &kiov; 3112 kuio.uio_segflg = UIO_SYSSPACE; 3113 kiov.iov_len = uap->count; 3114 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); 3115 kiov.iov_base = dirbuf; 3116 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 3117 NULL, NULL); 3118 fp->f_offset = kuio.uio_offset; 3119 if (error == 0) { 3120 readcnt = uap->count - kuio.uio_resid; 3121 edp = (struct dirent *)&dirbuf[readcnt]; 3122 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 3123 # if (BYTE_ORDER == LITTLE_ENDIAN) 3124 /* 3125 * The expected low byte of 3126 * dp->d_namlen is our dp->d_type. 3127 * The high MBZ byte of dp->d_namlen 3128 * is our dp->d_namlen. 3129 */ 3130 dp->d_type = dp->d_namlen; 3131 dp->d_namlen = 0; 3132 # else 3133 /* 3134 * The dp->d_type is the high byte 3135 * of the expected dp->d_namlen, 3136 * so must be zero'ed. 3137 */ 3138 dp->d_type = 0; 3139 # endif 3140 if (dp->d_reclen > 0) { 3141 dp = (struct dirent *) 3142 ((char *)dp + dp->d_reclen); 3143 } else { 3144 error = EIO; 3145 break; 3146 } 3147 } 3148 if (dp >= edp) 3149 error = uiomove(dirbuf, readcnt, &auio); 3150 } 3151 FREE(dirbuf, M_TEMP); 3152 } 3153 VOP_UNLOCK(vp, 0, td); 3154 if (error) { 3155 fdrop(fp, td); 3156 return (error); 3157 } 3158 if (uap->count == auio.uio_resid) { 3159 if (union_dircheckp) { 3160 error = union_dircheckp(td, &vp, fp); 3161 if (error == -1) 3162 goto unionread; 3163 if (error) { 3164 fdrop(fp, td); 3165 return (error); 3166 } 3167 } 3168 /* 3169 * XXX We could delay dropping the lock above but 3170 * union_dircheckp complicates things. 3171 */ 3172 vn_lock(vp, LK_EXCLUSIVE|LK_RETRY, td); 3173 if ((vp->v_vflag & VV_ROOT) && 3174 (vp->v_mount->mnt_flag & MNT_UNION)) { 3175 struct vnode *tvp = vp; 3176 vp = vp->v_mount->mnt_vnodecovered; 3177 VREF(vp); 3178 fp->f_data = vp; 3179 fp->f_offset = 0; 3180 vput(tvp); 3181 goto unionread; 3182 } 3183 VOP_UNLOCK(vp, 0, td); 3184 } 3185 error = copyout(&loff, uap->basep, sizeof(long)); 3186 fdrop(fp, td); 3187 td->td_retval[0] = uap->count - auio.uio_resid; 3188 return (error); 3189 } 3190 #endif /* COMPAT_43 */ 3191 3192 /* 3193 * Read a block of directory entries in a filesystem independent format. 3194 */ 3195 #ifndef _SYS_SYSPROTO_H_ 3196 struct getdirentries_args { 3197 int fd; 3198 char *buf; 3199 u_int count; 3200 long *basep; 3201 }; 3202 #endif 3203 int 3204 getdirentries(td, uap) 3205 struct thread *td; 3206 register struct getdirentries_args /* { 3207 int fd; 3208 char *buf; 3209 u_int count; 3210 long *basep; 3211 } */ *uap; 3212 { 3213 struct vnode *vp; 3214 struct file *fp; 3215 struct uio auio; 3216 struct iovec aiov; 3217 long loff; 3218 int error, eofflag; 3219 3220 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3221 return (error); 3222 if ((fp->f_flag & FREAD) == 0) { 3223 fdrop(fp, td); 3224 return (EBADF); 3225 } 3226 vp = fp->f_data; 3227 unionread: 3228 if (vp->v_type != VDIR) { 3229 fdrop(fp, td); 3230 return (EINVAL); 3231 } 3232 aiov.iov_base = uap->buf; 3233 aiov.iov_len = uap->count; 3234 auio.uio_iov = &aiov; 3235 auio.uio_iovcnt = 1; 3236 auio.uio_rw = UIO_READ; 3237 auio.uio_segflg = UIO_USERSPACE; 3238 auio.uio_td = td; 3239 auio.uio_resid = uap->count; 3240 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */ 3241 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3242 loff = auio.uio_offset = fp->f_offset; 3243 #ifdef MAC 3244 error = mac_check_vnode_readdir(td->td_ucred, vp); 3245 if (error == 0) 3246 #endif 3247 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, 3248 NULL); 3249 fp->f_offset = auio.uio_offset; 3250 VOP_UNLOCK(vp, 0, td); 3251 if (error) { 3252 fdrop(fp, td); 3253 return (error); 3254 } 3255 if (uap->count == auio.uio_resid) { 3256 if (union_dircheckp) { 3257 error = union_dircheckp(td, &vp, fp); 3258 if (error == -1) 3259 goto unionread; 3260 if (error) { 3261 fdrop(fp, td); 3262 return (error); 3263 } 3264 } 3265 /* 3266 * XXX We could delay dropping the lock above but 3267 * union_dircheckp complicates things. 3268 */ 3269 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3270 if ((vp->v_vflag & VV_ROOT) && 3271 (vp->v_mount->mnt_flag & MNT_UNION)) { 3272 struct vnode *tvp = vp; 3273 vp = vp->v_mount->mnt_vnodecovered; 3274 VREF(vp); 3275 fp->f_data = vp; 3276 fp->f_offset = 0; 3277 vput(tvp); 3278 goto unionread; 3279 } 3280 VOP_UNLOCK(vp, 0, td); 3281 } 3282 if (uap->basep != NULL) { 3283 error = copyout(&loff, uap->basep, sizeof(long)); 3284 } 3285 td->td_retval[0] = uap->count - auio.uio_resid; 3286 fdrop(fp, td); 3287 return (error); 3288 } 3289 #ifndef _SYS_SYSPROTO_H_ 3290 struct getdents_args { 3291 int fd; 3292 char *buf; 3293 size_t count; 3294 }; 3295 #endif 3296 int 3297 getdents(td, uap) 3298 struct thread *td; 3299 register struct getdents_args /* { 3300 int fd; 3301 char *buf; 3302 u_int count; 3303 } */ *uap; 3304 { 3305 struct getdirentries_args ap; 3306 ap.fd = uap->fd; 3307 ap.buf = uap->buf; 3308 ap.count = uap->count; 3309 ap.basep = NULL; 3310 return getdirentries(td, &ap); 3311 } 3312 3313 /* 3314 * Set the mode mask for creation of filesystem nodes. 3315 * 3316 * MP SAFE 3317 */ 3318 #ifndef _SYS_SYSPROTO_H_ 3319 struct umask_args { 3320 int newmask; 3321 }; 3322 #endif 3323 int 3324 umask(td, uap) 3325 struct thread *td; 3326 struct umask_args /* { 3327 int newmask; 3328 } */ *uap; 3329 { 3330 register struct filedesc *fdp; 3331 3332 FILEDESC_LOCK(td->td_proc->p_fd); 3333 fdp = td->td_proc->p_fd; 3334 td->td_retval[0] = fdp->fd_cmask; 3335 fdp->fd_cmask = uap->newmask & ALLPERMS; 3336 FILEDESC_UNLOCK(td->td_proc->p_fd); 3337 return (0); 3338 } 3339 3340 /* 3341 * Void all references to file by ripping underlying filesystem 3342 * away from vnode. 3343 */ 3344 #ifndef _SYS_SYSPROTO_H_ 3345 struct revoke_args { 3346 char *path; 3347 }; 3348 #endif 3349 /* ARGSUSED */ 3350 int 3351 revoke(td, uap) 3352 struct thread *td; 3353 register struct revoke_args /* { 3354 char *path; 3355 } */ *uap; 3356 { 3357 struct mount *mp; 3358 struct vnode *vp; 3359 struct vattr vattr; 3360 int error; 3361 struct nameidata nd; 3362 3363 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, td); 3364 if ((error = namei(&nd)) != 0) 3365 return (error); 3366 vp = nd.ni_vp; 3367 NDFREE(&nd, NDF_ONLY_PNBUF); 3368 if (vp->v_type != VCHR) { 3369 vput(vp); 3370 return (EINVAL); 3371 } 3372 #ifdef MAC 3373 error = mac_check_vnode_revoke(td->td_ucred, vp); 3374 if (error) { 3375 vput(vp); 3376 return (error); 3377 } 3378 #endif 3379 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td); 3380 if (error) { 3381 vput(vp); 3382 return (error); 3383 } 3384 VOP_UNLOCK(vp, 0, td); 3385 if (td->td_ucred->cr_uid != vattr.va_uid) { 3386 error = suser_cred(td->td_ucred, PRISON_ROOT); 3387 if (error) 3388 goto out; 3389 } 3390 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3391 goto out; 3392 if (vcount(vp) > 1) 3393 VOP_REVOKE(vp, REVOKEALL); 3394 vn_finished_write(mp); 3395 out: 3396 vrele(vp); 3397 return (error); 3398 } 3399 3400 /* 3401 * Convert a user file descriptor to a kernel file entry. 3402 * The file entry is locked upon returning. 3403 */ 3404 int 3405 getvnode(fdp, fd, fpp) 3406 struct filedesc *fdp; 3407 int fd; 3408 struct file **fpp; 3409 { 3410 int error; 3411 struct file *fp; 3412 3413 fp = NULL; 3414 if (fdp == NULL) 3415 error = EBADF; 3416 else { 3417 FILEDESC_LOCK(fdp); 3418 if ((u_int)fd >= fdp->fd_nfiles || 3419 (fp = fdp->fd_ofiles[fd]) == NULL) 3420 error = EBADF; 3421 else if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) { 3422 fp = NULL; 3423 error = EINVAL; 3424 } else { 3425 fhold(fp); 3426 error = 0; 3427 } 3428 FILEDESC_UNLOCK(fdp); 3429 } 3430 *fpp = fp; 3431 return (error); 3432 } 3433 /* 3434 * Get (NFS) file handle 3435 */ 3436 #ifndef _SYS_SYSPROTO_H_ 3437 struct getfh_args { 3438 char *fname; 3439 fhandle_t *fhp; 3440 }; 3441 #endif 3442 int 3443 getfh(td, uap) 3444 struct thread *td; 3445 register struct getfh_args *uap; 3446 { 3447 struct nameidata nd; 3448 fhandle_t fh; 3449 register struct vnode *vp; 3450 int error; 3451 3452 /* 3453 * Must be super user 3454 */ 3455 error = suser(td); 3456 if (error) 3457 return (error); 3458 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, td); 3459 error = namei(&nd); 3460 if (error) 3461 return (error); 3462 NDFREE(&nd, NDF_ONLY_PNBUF); 3463 vp = nd.ni_vp; 3464 bzero(&fh, sizeof(fh)); 3465 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 3466 error = VFS_VPTOFH(vp, &fh.fh_fid); 3467 vput(vp); 3468 if (error) 3469 return (error); 3470 error = copyout(&fh, uap->fhp, sizeof (fh)); 3471 return (error); 3472 } 3473 3474 /* 3475 * syscall for the rpc.lockd to use to translate a NFS file handle into 3476 * an open descriptor. 3477 * 3478 * warning: do not remove the suser() call or this becomes one giant 3479 * security hole. 3480 */ 3481 #ifndef _SYS_SYSPROTO_H_ 3482 struct fhopen_args { 3483 const struct fhandle *u_fhp; 3484 int flags; 3485 }; 3486 #endif 3487 int 3488 fhopen(td, uap) 3489 struct thread *td; 3490 struct fhopen_args /* { 3491 const struct fhandle *u_fhp; 3492 int flags; 3493 } */ *uap; 3494 { 3495 struct proc *p = td->td_proc; 3496 struct mount *mp; 3497 struct vnode *vp; 3498 struct fhandle fhp; 3499 struct vattr vat; 3500 struct vattr *vap = &vat; 3501 struct flock lf; 3502 struct file *fp; 3503 register struct filedesc *fdp = p->p_fd; 3504 int fmode, mode, error, type; 3505 struct file *nfp; 3506 int indx; 3507 3508 /* 3509 * Must be super user 3510 */ 3511 error = suser(td); 3512 if (error) 3513 return (error); 3514 3515 fmode = FFLAGS(uap->flags); 3516 /* why not allow a non-read/write open for our lockd? */ 3517 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 3518 return (EINVAL); 3519 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 3520 if (error) 3521 return(error); 3522 /* find the mount point */ 3523 mp = vfs_getvfs(&fhp.fh_fsid); 3524 if (mp == NULL) 3525 return (ESTALE); 3526 /* now give me my vnode, it gets returned to me locked */ 3527 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 3528 if (error) 3529 return (error); 3530 /* 3531 * from now on we have to make sure not 3532 * to forget about the vnode 3533 * any error that causes an abort must vput(vp) 3534 * just set error = err and 'goto bad;'. 3535 */ 3536 3537 /* 3538 * from vn_open 3539 */ 3540 if (vp->v_type == VLNK) { 3541 error = EMLINK; 3542 goto bad; 3543 } 3544 if (vp->v_type == VSOCK) { 3545 error = EOPNOTSUPP; 3546 goto bad; 3547 } 3548 mode = 0; 3549 if (fmode & (FWRITE | O_TRUNC)) { 3550 if (vp->v_type == VDIR) { 3551 error = EISDIR; 3552 goto bad; 3553 } 3554 error = vn_writechk(vp); 3555 if (error) 3556 goto bad; 3557 mode |= VWRITE; 3558 } 3559 if (fmode & FREAD) 3560 mode |= VREAD; 3561 if (fmode & O_APPEND) 3562 mode |= VAPPEND; 3563 #ifdef MAC 3564 error = mac_check_vnode_open(td->td_ucred, vp, mode); 3565 if (error) 3566 goto bad; 3567 #endif 3568 if (mode) { 3569 error = VOP_ACCESS(vp, mode, td->td_ucred, td); 3570 if (error) 3571 goto bad; 3572 } 3573 if (fmode & O_TRUNC) { 3574 VOP_UNLOCK(vp, 0, td); /* XXX */ 3575 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) { 3576 vrele(vp); 3577 return (error); 3578 } 3579 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3580 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */ 3581 #ifdef MAC 3582 /* 3583 * We don't yet have fp->f_cred, so use td->td_ucred, which 3584 * should be right. 3585 */ 3586 error = mac_check_vnode_write(td->td_ucred, td->td_ucred, vp); 3587 if (error == 0) { 3588 #endif 3589 VATTR_NULL(vap); 3590 vap->va_size = 0; 3591 error = VOP_SETATTR(vp, vap, td->td_ucred, td); 3592 #ifdef MAC 3593 } 3594 #endif 3595 vn_finished_write(mp); 3596 if (error) 3597 goto bad; 3598 } 3599 error = VOP_OPEN(vp, fmode, td->td_ucred, td); 3600 if (error) 3601 goto bad; 3602 /* 3603 * Make sure that a VM object is created for VMIO support. 3604 */ 3605 if (vn_canvmio(vp) == TRUE) { 3606 if ((error = vfs_object_create(vp, td, td->td_ucred)) != 0) 3607 goto bad; 3608 } 3609 if (fmode & FWRITE) 3610 vp->v_writecount++; 3611 3612 /* 3613 * end of vn_open code 3614 */ 3615 3616 if ((error = falloc(td, &nfp, &indx)) != 0) { 3617 if (fmode & FWRITE) 3618 vp->v_writecount--; 3619 goto bad; 3620 } 3621 fp = nfp; 3622 3623 /* 3624 * Hold an extra reference to avoid having fp ripped out 3625 * from under us while we block in the lock op 3626 */ 3627 fhold(fp); 3628 nfp->f_data = vp; 3629 nfp->f_flag = fmode & FMASK; 3630 nfp->f_ops = &vnops; 3631 nfp->f_type = DTYPE_VNODE; 3632 if (fmode & (O_EXLOCK | O_SHLOCK)) { 3633 lf.l_whence = SEEK_SET; 3634 lf.l_start = 0; 3635 lf.l_len = 0; 3636 if (fmode & O_EXLOCK) 3637 lf.l_type = F_WRLCK; 3638 else 3639 lf.l_type = F_RDLCK; 3640 type = F_FLOCK; 3641 if ((fmode & FNONBLOCK) == 0) 3642 type |= F_WAIT; 3643 VOP_UNLOCK(vp, 0, td); 3644 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 3645 type)) != 0) { 3646 /* 3647 * The lock request failed. Normally close the 3648 * descriptor but handle the case where someone might 3649 * have dup()d or close()d it when we weren't looking. 3650 */ 3651 FILEDESC_LOCK(fdp); 3652 if (fdp->fd_ofiles[indx] == fp) { 3653 fdp->fd_ofiles[indx] = NULL; 3654 FILEDESC_UNLOCK(fdp); 3655 fdrop(fp, td); 3656 } else 3657 FILEDESC_UNLOCK(fdp); 3658 /* 3659 * release our private reference 3660 */ 3661 fdrop(fp, td); 3662 return(error); 3663 } 3664 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3665 fp->f_flag |= FHASLOCK; 3666 } 3667 if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0)) 3668 vfs_object_create(vp, td, td->td_ucred); 3669 3670 VOP_UNLOCK(vp, 0, td); 3671 fdrop(fp, td); 3672 td->td_retval[0] = indx; 3673 return (0); 3674 3675 bad: 3676 vput(vp); 3677 return (error); 3678 } 3679 3680 /* 3681 * Stat an (NFS) file handle. 3682 */ 3683 #ifndef _SYS_SYSPROTO_H_ 3684 struct fhstat_args { 3685 struct fhandle *u_fhp; 3686 struct stat *sb; 3687 }; 3688 #endif 3689 int 3690 fhstat(td, uap) 3691 struct thread *td; 3692 register struct fhstat_args /* { 3693 struct fhandle *u_fhp; 3694 struct stat *sb; 3695 } */ *uap; 3696 { 3697 struct stat sb; 3698 fhandle_t fh; 3699 struct mount *mp; 3700 struct vnode *vp; 3701 int error; 3702 3703 /* 3704 * Must be super user 3705 */ 3706 error = suser(td); 3707 if (error) 3708 return (error); 3709 3710 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 3711 if (error) 3712 return (error); 3713 3714 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3715 return (ESTALE); 3716 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3717 return (error); 3718 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 3719 vput(vp); 3720 if (error) 3721 return (error); 3722 error = copyout(&sb, uap->sb, sizeof(sb)); 3723 return (error); 3724 } 3725 3726 /* 3727 * Implement fstatfs() for (NFS) file handles. 3728 */ 3729 #ifndef _SYS_SYSPROTO_H_ 3730 struct fhstatfs_args { 3731 struct fhandle *u_fhp; 3732 struct statfs *buf; 3733 }; 3734 #endif 3735 int 3736 fhstatfs(td, uap) 3737 struct thread *td; 3738 struct fhstatfs_args /* { 3739 struct fhandle *u_fhp; 3740 struct statfs *buf; 3741 } */ *uap; 3742 { 3743 struct statfs *sp; 3744 struct mount *mp; 3745 struct vnode *vp; 3746 struct statfs sb; 3747 fhandle_t fh; 3748 int error; 3749 3750 /* 3751 * Must be super user 3752 */ 3753 error = suser(td); 3754 if (error) 3755 return (error); 3756 3757 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 3758 return (error); 3759 3760 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3761 return (ESTALE); 3762 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3763 return (error); 3764 mp = vp->v_mount; 3765 sp = &mp->mnt_stat; 3766 vput(vp); 3767 #ifdef MAC 3768 error = mac_check_mount_stat(td->td_ucred, mp); 3769 if (error) 3770 return (error); 3771 #endif 3772 if ((error = VFS_STATFS(mp, sp, td)) != 0) 3773 return (error); 3774 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 3775 if (suser(td)) { 3776 bcopy(sp, &sb, sizeof(sb)); 3777 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 3778 sp = &sb; 3779 } 3780 return (copyout(sp, uap->buf, sizeof(*sp))); 3781 } 3782 3783 /* 3784 * Syscall to push extended attribute configuration information into the 3785 * VFS. Accepts a path, which it converts to a mountpoint, as well as 3786 * a command (int cmd), and attribute name and misc data. For now, the 3787 * attribute name is left in userspace for consumption by the VFS_op. 3788 * It will probably be changed to be copied into sysspace by the 3789 * syscall in the future, once issues with various consumers of the 3790 * attribute code have raised their hands. 3791 * 3792 * Currently this is used only by UFS Extended Attributes. 3793 */ 3794 int 3795 extattrctl(td, uap) 3796 struct thread *td; 3797 struct extattrctl_args /* { 3798 const char *path; 3799 int cmd; 3800 const char *filename; 3801 int attrnamespace; 3802 const char *attrname; 3803 } */ *uap; 3804 { 3805 struct vnode *filename_vp; 3806 struct nameidata nd; 3807 struct mount *mp, *mp_writable; 3808 char attrname[EXTATTR_MAXNAMELEN]; 3809 int error; 3810 3811 /* 3812 * uap->attrname is not always defined. We check again later when we 3813 * invoke the VFS call so as to pass in NULL there if needed. 3814 */ 3815 if (uap->attrname != NULL) { 3816 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, 3817 NULL); 3818 if (error) 3819 return (error); 3820 } 3821 3822 /* 3823 * uap->filename is not always defined. If it is, grab a vnode lock, 3824 * which VFS_EXTATTRCTL() will later release. 3825 */ 3826 filename_vp = NULL; 3827 if (uap->filename != NULL) { 3828 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 3829 uap->filename, td); 3830 error = namei(&nd); 3831 if (error) 3832 return (error); 3833 filename_vp = nd.ni_vp; 3834 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK); 3835 } 3836 3837 /* uap->path is always defined. */ 3838 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 3839 error = namei(&nd); 3840 if (error) { 3841 if (filename_vp != NULL) 3842 vput(filename_vp); 3843 return (error); 3844 } 3845 mp = nd.ni_vp->v_mount; 3846 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH); 3847 NDFREE(&nd, 0); 3848 if (error) { 3849 if (filename_vp != NULL) 3850 vput(filename_vp); 3851 return (error); 3852 } 3853 3854 error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace, 3855 uap->attrname != NULL ? attrname : NULL, td); 3856 3857 vn_finished_write(mp_writable); 3858 /* 3859 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd, 3860 * filename_vp, so vrele it if it is defined. 3861 */ 3862 if (filename_vp != NULL) 3863 vrele(filename_vp); 3864 return (error); 3865 } 3866 3867 /*- 3868 * Set a named extended attribute on a file or directory 3869 * 3870 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace", 3871 * kernelspace string pointer "attrname", userspace buffer 3872 * pointer "data", buffer length "nbytes", thread "td". 3873 * Returns: 0 on success, an error number otherwise 3874 * Locks: none 3875 * References: vp must be a valid reference for the duration of the call 3876 */ 3877 static int 3878 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname, 3879 void *data, size_t nbytes, struct thread *td) 3880 { 3881 struct mount *mp; 3882 struct uio auio; 3883 struct iovec aiov; 3884 ssize_t cnt; 3885 int error; 3886 3887 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3888 if (error) 3889 return (error); 3890 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3891 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3892 3893 aiov.iov_base = data; 3894 aiov.iov_len = nbytes; 3895 auio.uio_iov = &aiov; 3896 auio.uio_iovcnt = 1; 3897 auio.uio_offset = 0; 3898 if (nbytes > INT_MAX) { 3899 error = EINVAL; 3900 goto done; 3901 } 3902 auio.uio_resid = nbytes; 3903 auio.uio_rw = UIO_WRITE; 3904 auio.uio_segflg = UIO_USERSPACE; 3905 auio.uio_td = td; 3906 cnt = nbytes; 3907 3908 #ifdef MAC 3909 error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace, 3910 attrname, &auio); 3911 if (error) 3912 goto done; 3913 #endif 3914 3915 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, 3916 td->td_ucred, td); 3917 cnt -= auio.uio_resid; 3918 td->td_retval[0] = cnt; 3919 3920 done: 3921 VOP_UNLOCK(vp, 0, td); 3922 vn_finished_write(mp); 3923 return (error); 3924 } 3925 3926 int 3927 extattr_set_fd(td, uap) 3928 struct thread *td; 3929 struct extattr_set_fd_args /* { 3930 int fd; 3931 int attrnamespace; 3932 const char *attrname; 3933 void *data; 3934 size_t nbytes; 3935 } */ *uap; 3936 { 3937 struct file *fp; 3938 char attrname[EXTATTR_MAXNAMELEN]; 3939 int error; 3940 3941 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 3942 if (error) 3943 return (error); 3944 3945 error = getvnode(td->td_proc->p_fd, uap->fd, &fp); 3946 if (error) 3947 return (error); 3948 3949 error = extattr_set_vp(fp->f_data, uap->attrnamespace, 3950 attrname, uap->data, uap->nbytes, td); 3951 fdrop(fp, td); 3952 3953 return (error); 3954 } 3955 3956 int 3957 extattr_set_file(td, uap) 3958 struct thread *td; 3959 struct extattr_set_file_args /* { 3960 const char *path; 3961 int attrnamespace; 3962 const char *attrname; 3963 void *data; 3964 size_t nbytes; 3965 } */ *uap; 3966 { 3967 struct nameidata nd; 3968 char attrname[EXTATTR_MAXNAMELEN]; 3969 int error; 3970 3971 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 3972 if (error) 3973 return (error); 3974 3975 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 3976 error = namei(&nd); 3977 if (error) 3978 return (error); 3979 NDFREE(&nd, NDF_ONLY_PNBUF); 3980 3981 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname, 3982 uap->data, uap->nbytes, td); 3983 3984 vrele(nd.ni_vp); 3985 return (error); 3986 } 3987 3988 int 3989 extattr_set_link(td, uap) 3990 struct thread *td; 3991 struct extattr_set_link_args /* { 3992 const char *path; 3993 int attrnamespace; 3994 const char *attrname; 3995 void *data; 3996 size_t nbytes; 3997 } */ *uap; 3998 { 3999 struct nameidata nd; 4000 char attrname[EXTATTR_MAXNAMELEN]; 4001 int error; 4002 4003 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4004 if (error) 4005 return (error); 4006 4007 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td); 4008 error = namei(&nd); 4009 if (error) 4010 return (error); 4011 NDFREE(&nd, NDF_ONLY_PNBUF); 4012 4013 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname, 4014 uap->data, uap->nbytes, td); 4015 4016 vrele(nd.ni_vp); 4017 return (error); 4018 } 4019 4020 /*- 4021 * Get a named extended attribute on a file or directory 4022 * 4023 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace", 4024 * kernelspace string pointer "attrname", userspace buffer 4025 * pointer "data", buffer length "nbytes", thread "td". 4026 * Returns: 0 on success, an error number otherwise 4027 * Locks: none 4028 * References: vp must be a valid reference for the duration of the call 4029 */ 4030 static int 4031 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname, 4032 void *data, size_t nbytes, struct thread *td) 4033 { 4034 struct uio auio, *auiop; 4035 struct iovec aiov; 4036 ssize_t cnt; 4037 size_t size, *sizep; 4038 int error; 4039 4040 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ); 4041 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 4042 4043 /* 4044 * Slightly unusual semantics: if the user provides a NULL data 4045 * pointer, they don't want to receive the data, just the 4046 * maximum read length. 4047 */ 4048 auiop = NULL; 4049 sizep = NULL; 4050 cnt = 0; 4051 if (data != NULL) { 4052 aiov.iov_base = data; 4053 aiov.iov_len = nbytes; 4054 auio.uio_iov = &aiov; 4055 auio.uio_offset = 0; 4056 if (nbytes > INT_MAX) { 4057 error = EINVAL; 4058 goto done; 4059 } 4060 auio.uio_resid = nbytes; 4061 auio.uio_rw = UIO_READ; 4062 auio.uio_segflg = UIO_USERSPACE; 4063 auio.uio_td = td; 4064 auiop = &auio; 4065 cnt = nbytes; 4066 } else 4067 sizep = &size; 4068 4069 #ifdef MAC 4070 error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace, 4071 attrname, &auio); 4072 if (error) 4073 goto done; 4074 #endif 4075 4076 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep, 4077 td->td_ucred, td); 4078 4079 if (auiop != NULL) { 4080 cnt -= auio.uio_resid; 4081 td->td_retval[0] = cnt; 4082 } else 4083 td->td_retval[0] = size; 4084 4085 done: 4086 VOP_UNLOCK(vp, 0, td); 4087 return (error); 4088 } 4089 4090 int 4091 extattr_get_fd(td, uap) 4092 struct thread *td; 4093 struct extattr_get_fd_args /* { 4094 int fd; 4095 int attrnamespace; 4096 const char *attrname; 4097 void *data; 4098 size_t nbytes; 4099 } */ *uap; 4100 { 4101 struct file *fp; 4102 char attrname[EXTATTR_MAXNAMELEN]; 4103 int error; 4104 4105 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4106 if (error) 4107 return (error); 4108 4109 error = getvnode(td->td_proc->p_fd, uap->fd, &fp); 4110 if (error) 4111 return (error); 4112 4113 error = extattr_get_vp(fp->f_data, uap->attrnamespace, 4114 attrname, uap->data, uap->nbytes, td); 4115 4116 fdrop(fp, td); 4117 return (error); 4118 } 4119 4120 int 4121 extattr_get_file(td, uap) 4122 struct thread *td; 4123 struct extattr_get_file_args /* { 4124 const char *path; 4125 int attrnamespace; 4126 const char *attrname; 4127 void *data; 4128 size_t nbytes; 4129 } */ *uap; 4130 { 4131 struct nameidata nd; 4132 char attrname[EXTATTR_MAXNAMELEN]; 4133 int error; 4134 4135 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4136 if (error) 4137 return (error); 4138 4139 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 4140 error = namei(&nd); 4141 if (error) 4142 return (error); 4143 NDFREE(&nd, NDF_ONLY_PNBUF); 4144 4145 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname, 4146 uap->data, uap->nbytes, td); 4147 4148 vrele(nd.ni_vp); 4149 return (error); 4150 } 4151 4152 int 4153 extattr_get_link(td, uap) 4154 struct thread *td; 4155 struct extattr_get_link_args /* { 4156 const char *path; 4157 int attrnamespace; 4158 const char *attrname; 4159 void *data; 4160 size_t nbytes; 4161 } */ *uap; 4162 { 4163 struct nameidata nd; 4164 char attrname[EXTATTR_MAXNAMELEN]; 4165 int error; 4166 4167 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4168 if (error) 4169 return (error); 4170 4171 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td); 4172 error = namei(&nd); 4173 if (error) 4174 return (error); 4175 NDFREE(&nd, NDF_ONLY_PNBUF); 4176 4177 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname, 4178 uap->data, uap->nbytes, td); 4179 4180 vrele(nd.ni_vp); 4181 return (error); 4182 } 4183 4184 /* 4185 * extattr_delete_vp(): Delete a named extended attribute on a file or 4186 * directory 4187 * 4188 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace", 4189 * kernelspace string pointer "attrname", proc "p" 4190 * Returns: 0 on success, an error number otherwise 4191 * Locks: none 4192 * References: vp must be a valid reference for the duration of the call 4193 */ 4194 static int 4195 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, 4196 struct thread *td) 4197 { 4198 struct mount *mp; 4199 int error; 4200 4201 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 4202 if (error) 4203 return (error); 4204 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 4205 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 4206 4207 #ifdef MAC 4208 error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace, 4209 attrname, NULL); 4210 if (error) 4211 goto done; 4212 #endif 4213 4214 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred, 4215 td); 4216 #ifdef MAC 4217 done: 4218 #endif 4219 VOP_UNLOCK(vp, 0, td); 4220 vn_finished_write(mp); 4221 return (error); 4222 } 4223 4224 int 4225 extattr_delete_fd(td, uap) 4226 struct thread *td; 4227 struct extattr_delete_fd_args /* { 4228 int fd; 4229 int attrnamespace; 4230 const char *attrname; 4231 } */ *uap; 4232 { 4233 struct file *fp; 4234 struct vnode *vp; 4235 char attrname[EXTATTR_MAXNAMELEN]; 4236 int error; 4237 4238 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4239 if (error) 4240 return (error); 4241 4242 error = getvnode(td->td_proc->p_fd, uap->fd, &fp); 4243 if (error) 4244 return (error); 4245 vp = fp->f_data; 4246 4247 error = extattr_delete_vp(vp, uap->attrnamespace, attrname, td); 4248 fdrop(fp, td); 4249 return (error); 4250 } 4251 4252 int 4253 extattr_delete_file(td, uap) 4254 struct thread *td; 4255 struct extattr_delete_file_args /* { 4256 const char *path; 4257 int attrnamespace; 4258 const char *attrname; 4259 } */ *uap; 4260 { 4261 struct nameidata nd; 4262 char attrname[EXTATTR_MAXNAMELEN]; 4263 int error; 4264 4265 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4266 if (error) 4267 return(error); 4268 4269 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); 4270 error = namei(&nd); 4271 if (error) 4272 return(error); 4273 NDFREE(&nd, NDF_ONLY_PNBUF); 4274 4275 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td); 4276 vrele(nd.ni_vp); 4277 return(error); 4278 } 4279 4280 int 4281 extattr_delete_link(td, uap) 4282 struct thread *td; 4283 struct extattr_delete_link_args /* { 4284 const char *path; 4285 int attrnamespace; 4286 const char *attrname; 4287 } */ *uap; 4288 { 4289 struct nameidata nd; 4290 char attrname[EXTATTR_MAXNAMELEN]; 4291 int error; 4292 4293 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); 4294 if (error) 4295 return(error); 4296 4297 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td); 4298 error = namei(&nd); 4299 if (error) 4300 return(error); 4301 NDFREE(&nd, NDF_ONLY_PNBUF); 4302 4303 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td); 4304 vrele(nd.ni_vp); 4305 return(error); 4306 } 4307