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