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