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