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