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)) { 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); 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))) { 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); 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)) { 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); 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); 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); 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)) 745 continue; 746 tvfslocked = VFS_LOCK_GIANT(mp); 747 error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td); 748 vfs_unbusy(mp); 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); 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 case S_IFIFO: 1268 if (dev == 0) 1269 return (kern_mkfifoat(td, fd, path, pathseg, mode)); 1270 /* FALLTHROUGH */ 1271 default: 1272 error = EINVAL; 1273 break; 1274 } 1275 if (error) 1276 return (error); 1277 restart: 1278 bwillwrite(); 1279 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1280 pathseg, path, fd, td); 1281 if ((error = namei(&nd)) != 0) 1282 return (error); 1283 vfslocked = NDHASGIANT(&nd); 1284 vp = nd.ni_vp; 1285 if (vp != NULL) { 1286 NDFREE(&nd, NDF_ONLY_PNBUF); 1287 if (vp == nd.ni_dvp) 1288 vrele(nd.ni_dvp); 1289 else 1290 vput(nd.ni_dvp); 1291 vrele(vp); 1292 VFS_UNLOCK_GIANT(vfslocked); 1293 return (EEXIST); 1294 } else { 1295 VATTR_NULL(&vattr); 1296 FILEDESC_SLOCK(td->td_proc->p_fd); 1297 vattr.va_mode = (mode & ALLPERMS) & 1298 ~td->td_proc->p_fd->fd_cmask; 1299 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1300 vattr.va_rdev = dev; 1301 whiteout = 0; 1302 1303 switch (mode & S_IFMT) { 1304 case S_IFMT: /* used by badsect to flag bad sectors */ 1305 vattr.va_type = VBAD; 1306 break; 1307 case S_IFCHR: 1308 vattr.va_type = VCHR; 1309 break; 1310 case S_IFBLK: 1311 vattr.va_type = VBLK; 1312 break; 1313 case S_IFWHT: 1314 whiteout = 1; 1315 break; 1316 default: 1317 panic("kern_mknod: invalid mode"); 1318 } 1319 } 1320 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1321 NDFREE(&nd, NDF_ONLY_PNBUF); 1322 vput(nd.ni_dvp); 1323 VFS_UNLOCK_GIANT(vfslocked); 1324 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1325 return (error); 1326 goto restart; 1327 } 1328 #ifdef MAC 1329 if (error == 0 && !whiteout) 1330 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, 1331 &nd.ni_cnd, &vattr); 1332 #endif 1333 if (!error) { 1334 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1335 if (whiteout) 1336 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1337 else { 1338 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1339 &nd.ni_cnd, &vattr); 1340 if (error == 0) 1341 vput(nd.ni_vp); 1342 } 1343 } 1344 NDFREE(&nd, NDF_ONLY_PNBUF); 1345 vput(nd.ni_dvp); 1346 vn_finished_write(mp); 1347 VFS_UNLOCK_GIANT(vfslocked); 1348 return (error); 1349 } 1350 1351 /* 1352 * Create a named pipe. 1353 */ 1354 #ifndef _SYS_SYSPROTO_H_ 1355 struct mkfifo_args { 1356 char *path; 1357 int mode; 1358 }; 1359 #endif 1360 int 1361 mkfifo(td, uap) 1362 struct thread *td; 1363 register struct mkfifo_args /* { 1364 char *path; 1365 int mode; 1366 } */ *uap; 1367 { 1368 1369 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); 1370 } 1371 1372 #ifndef _SYS_SYSPROTO_H_ 1373 struct mkfifoat_args { 1374 int fd; 1375 char *path; 1376 mode_t mode; 1377 }; 1378 #endif 1379 int 1380 mkfifoat(struct thread *td, struct mkfifoat_args *uap) 1381 { 1382 1383 return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE, 1384 uap->mode)); 1385 } 1386 1387 int 1388 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) 1389 { 1390 1391 return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode)); 1392 } 1393 1394 int 1395 kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1396 int mode) 1397 { 1398 struct mount *mp; 1399 struct vattr vattr; 1400 int error; 1401 struct nameidata nd; 1402 int vfslocked; 1403 1404 AUDIT_ARG(mode, mode); 1405 restart: 1406 bwillwrite(); 1407 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1408 pathseg, path, fd, td); 1409 if ((error = namei(&nd)) != 0) 1410 return (error); 1411 vfslocked = NDHASGIANT(&nd); 1412 if (nd.ni_vp != NULL) { 1413 NDFREE(&nd, NDF_ONLY_PNBUF); 1414 if (nd.ni_vp == nd.ni_dvp) 1415 vrele(nd.ni_dvp); 1416 else 1417 vput(nd.ni_dvp); 1418 vrele(nd.ni_vp); 1419 VFS_UNLOCK_GIANT(vfslocked); 1420 return (EEXIST); 1421 } 1422 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1423 NDFREE(&nd, NDF_ONLY_PNBUF); 1424 vput(nd.ni_dvp); 1425 VFS_UNLOCK_GIANT(vfslocked); 1426 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1427 return (error); 1428 goto restart; 1429 } 1430 VATTR_NULL(&vattr); 1431 vattr.va_type = VFIFO; 1432 FILEDESC_SLOCK(td->td_proc->p_fd); 1433 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; 1434 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1435 #ifdef MAC 1436 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1437 &vattr); 1438 if (error) 1439 goto out; 1440 #endif 1441 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1442 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1443 if (error == 0) 1444 vput(nd.ni_vp); 1445 #ifdef MAC 1446 out: 1447 #endif 1448 vput(nd.ni_dvp); 1449 vn_finished_write(mp); 1450 VFS_UNLOCK_GIANT(vfslocked); 1451 NDFREE(&nd, NDF_ONLY_PNBUF); 1452 return (error); 1453 } 1454 1455 /* 1456 * Make a hard file link. 1457 */ 1458 #ifndef _SYS_SYSPROTO_H_ 1459 struct link_args { 1460 char *path; 1461 char *link; 1462 }; 1463 #endif 1464 int 1465 link(td, uap) 1466 struct thread *td; 1467 register struct link_args /* { 1468 char *path; 1469 char *link; 1470 } */ *uap; 1471 { 1472 1473 return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); 1474 } 1475 1476 #ifndef _SYS_SYSPROTO_H_ 1477 struct linkat_args { 1478 int fd1; 1479 char *path1; 1480 int fd2; 1481 char *path2; 1482 int flag; 1483 }; 1484 #endif 1485 int 1486 linkat(struct thread *td, struct linkat_args *uap) 1487 { 1488 int flag; 1489 1490 flag = uap->flag; 1491 if (flag & ~AT_SYMLINK_FOLLOW) 1492 return (EINVAL); 1493 1494 return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, 1495 UIO_USERSPACE, (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW)); 1496 } 1497 1498 static int hardlink_check_uid = 0; 1499 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, 1500 &hardlink_check_uid, 0, 1501 "Unprivileged processes cannot create hard links to files owned by other " 1502 "users"); 1503 static int hardlink_check_gid = 0; 1504 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, 1505 &hardlink_check_gid, 0, 1506 "Unprivileged processes cannot create hard links to files owned by other " 1507 "groups"); 1508 1509 static int 1510 can_hardlink(struct vnode *vp, struct ucred *cred) 1511 { 1512 struct vattr va; 1513 int error; 1514 1515 if (!hardlink_check_uid && !hardlink_check_gid) 1516 return (0); 1517 1518 error = VOP_GETATTR(vp, &va, cred); 1519 if (error != 0) 1520 return (error); 1521 1522 if (hardlink_check_uid && cred->cr_uid != va.va_uid) { 1523 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1524 if (error) 1525 return (error); 1526 } 1527 1528 if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { 1529 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1530 if (error) 1531 return (error); 1532 } 1533 1534 return (0); 1535 } 1536 1537 int 1538 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) 1539 { 1540 1541 return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW)); 1542 } 1543 1544 int 1545 kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, 1546 enum uio_seg segflg, int follow) 1547 { 1548 struct vnode *vp; 1549 struct mount *mp; 1550 struct nameidata nd; 1551 int vfslocked; 1552 int lvfslocked; 1553 int error; 1554 1555 bwillwrite(); 1556 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, segflg, path1, 1557 fd1, td); 1558 1559 if ((error = namei(&nd)) != 0) 1560 return (error); 1561 vfslocked = NDHASGIANT(&nd); 1562 NDFREE(&nd, NDF_ONLY_PNBUF); 1563 vp = nd.ni_vp; 1564 if (vp->v_type == VDIR) { 1565 vrele(vp); 1566 VFS_UNLOCK_GIANT(vfslocked); 1567 return (EPERM); /* POSIX */ 1568 } 1569 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 1570 vrele(vp); 1571 VFS_UNLOCK_GIANT(vfslocked); 1572 return (error); 1573 } 1574 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1575 segflg, path2, fd2, td); 1576 if ((error = namei(&nd)) == 0) { 1577 lvfslocked = NDHASGIANT(&nd); 1578 if (nd.ni_vp != NULL) { 1579 if (nd.ni_dvp == nd.ni_vp) 1580 vrele(nd.ni_dvp); 1581 else 1582 vput(nd.ni_dvp); 1583 vrele(nd.ni_vp); 1584 error = EEXIST; 1585 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) 1586 == 0) { 1587 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1588 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 1589 error = can_hardlink(vp, td->td_ucred); 1590 if (error == 0) 1591 #ifdef MAC 1592 error = mac_vnode_check_link(td->td_ucred, 1593 nd.ni_dvp, vp, &nd.ni_cnd); 1594 if (error == 0) 1595 #endif 1596 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1597 VOP_UNLOCK(vp, 0); 1598 vput(nd.ni_dvp); 1599 } 1600 NDFREE(&nd, NDF_ONLY_PNBUF); 1601 VFS_UNLOCK_GIANT(lvfslocked); 1602 } 1603 vrele(vp); 1604 vn_finished_write(mp); 1605 VFS_UNLOCK_GIANT(vfslocked); 1606 return (error); 1607 } 1608 1609 /* 1610 * Make a symbolic link. 1611 */ 1612 #ifndef _SYS_SYSPROTO_H_ 1613 struct symlink_args { 1614 char *path; 1615 char *link; 1616 }; 1617 #endif 1618 int 1619 symlink(td, uap) 1620 struct thread *td; 1621 register struct symlink_args /* { 1622 char *path; 1623 char *link; 1624 } */ *uap; 1625 { 1626 1627 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); 1628 } 1629 1630 #ifndef _SYS_SYSPROTO_H_ 1631 struct symlinkat_args { 1632 char *path; 1633 int fd; 1634 char *path2; 1635 }; 1636 #endif 1637 int 1638 symlinkat(struct thread *td, struct symlinkat_args *uap) 1639 { 1640 1641 return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2, 1642 UIO_USERSPACE)); 1643 } 1644 1645 int 1646 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) 1647 { 1648 1649 return (kern_symlinkat(td, path, AT_FDCWD, link, segflg)); 1650 } 1651 1652 int 1653 kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, 1654 enum uio_seg segflg) 1655 { 1656 struct mount *mp; 1657 struct vattr vattr; 1658 char *syspath; 1659 int error; 1660 struct nameidata nd; 1661 int vfslocked; 1662 1663 if (segflg == UIO_SYSSPACE) { 1664 syspath = path1; 1665 } else { 1666 syspath = uma_zalloc(namei_zone, M_WAITOK); 1667 if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0) 1668 goto out; 1669 } 1670 AUDIT_ARG(text, syspath); 1671 restart: 1672 bwillwrite(); 1673 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1674 segflg, path2, fd, td); 1675 if ((error = namei(&nd)) != 0) 1676 goto out; 1677 vfslocked = NDHASGIANT(&nd); 1678 if (nd.ni_vp) { 1679 NDFREE(&nd, NDF_ONLY_PNBUF); 1680 if (nd.ni_vp == nd.ni_dvp) 1681 vrele(nd.ni_dvp); 1682 else 1683 vput(nd.ni_dvp); 1684 vrele(nd.ni_vp); 1685 VFS_UNLOCK_GIANT(vfslocked); 1686 error = EEXIST; 1687 goto out; 1688 } 1689 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1690 NDFREE(&nd, NDF_ONLY_PNBUF); 1691 vput(nd.ni_dvp); 1692 VFS_UNLOCK_GIANT(vfslocked); 1693 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1694 goto out; 1695 goto restart; 1696 } 1697 VATTR_NULL(&vattr); 1698 FILEDESC_SLOCK(td->td_proc->p_fd); 1699 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; 1700 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1701 #ifdef MAC 1702 vattr.va_type = VLNK; 1703 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1704 &vattr); 1705 if (error) 1706 goto out2; 1707 #endif 1708 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1709 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); 1710 if (error == 0) 1711 vput(nd.ni_vp); 1712 #ifdef MAC 1713 out2: 1714 #endif 1715 NDFREE(&nd, NDF_ONLY_PNBUF); 1716 vput(nd.ni_dvp); 1717 vn_finished_write(mp); 1718 VFS_UNLOCK_GIANT(vfslocked); 1719 out: 1720 if (segflg != UIO_SYSSPACE) 1721 uma_zfree(namei_zone, syspath); 1722 return (error); 1723 } 1724 1725 /* 1726 * Delete a whiteout from the filesystem. 1727 */ 1728 int 1729 undelete(td, uap) 1730 struct thread *td; 1731 register struct undelete_args /* { 1732 char *path; 1733 } */ *uap; 1734 { 1735 int error; 1736 struct mount *mp; 1737 struct nameidata nd; 1738 int vfslocked; 1739 1740 restart: 1741 bwillwrite(); 1742 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1, 1743 UIO_USERSPACE, uap->path, td); 1744 error = namei(&nd); 1745 if (error) 1746 return (error); 1747 vfslocked = NDHASGIANT(&nd); 1748 1749 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1750 NDFREE(&nd, NDF_ONLY_PNBUF); 1751 if (nd.ni_vp == nd.ni_dvp) 1752 vrele(nd.ni_dvp); 1753 else 1754 vput(nd.ni_dvp); 1755 if (nd.ni_vp) 1756 vrele(nd.ni_vp); 1757 VFS_UNLOCK_GIANT(vfslocked); 1758 return (EEXIST); 1759 } 1760 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1761 NDFREE(&nd, NDF_ONLY_PNBUF); 1762 vput(nd.ni_dvp); 1763 VFS_UNLOCK_GIANT(vfslocked); 1764 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1765 return (error); 1766 goto restart; 1767 } 1768 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1769 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); 1770 NDFREE(&nd, NDF_ONLY_PNBUF); 1771 vput(nd.ni_dvp); 1772 vn_finished_write(mp); 1773 VFS_UNLOCK_GIANT(vfslocked); 1774 return (error); 1775 } 1776 1777 /* 1778 * Delete a name from the filesystem. 1779 */ 1780 #ifndef _SYS_SYSPROTO_H_ 1781 struct unlink_args { 1782 char *path; 1783 }; 1784 #endif 1785 int 1786 unlink(td, uap) 1787 struct thread *td; 1788 struct unlink_args /* { 1789 char *path; 1790 } */ *uap; 1791 { 1792 1793 return (kern_unlink(td, uap->path, UIO_USERSPACE)); 1794 } 1795 1796 #ifndef _SYS_SYSPROTO_H_ 1797 struct unlinkat_args { 1798 int fd; 1799 char *path; 1800 int flag; 1801 }; 1802 #endif 1803 int 1804 unlinkat(struct thread *td, struct unlinkat_args *uap) 1805 { 1806 int flag = uap->flag; 1807 int fd = uap->fd; 1808 char *path = uap->path; 1809 1810 if (flag & ~AT_REMOVEDIR) 1811 return (EINVAL); 1812 1813 if (flag & AT_REMOVEDIR) 1814 return (kern_rmdirat(td, fd, path, UIO_USERSPACE)); 1815 else 1816 return (kern_unlinkat(td, fd, path, UIO_USERSPACE)); 1817 } 1818 1819 int 1820 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) 1821 { 1822 1823 return (kern_unlinkat(td, AT_FDCWD, path, pathseg)); 1824 } 1825 1826 int 1827 kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 1828 { 1829 struct mount *mp; 1830 struct vnode *vp; 1831 int error; 1832 struct nameidata nd; 1833 int vfslocked; 1834 1835 restart: 1836 bwillwrite(); 1837 NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, 1838 pathseg, path, fd, td); 1839 if ((error = namei(&nd)) != 0) 1840 return (error == EINVAL ? EPERM : error); 1841 vfslocked = NDHASGIANT(&nd); 1842 vp = nd.ni_vp; 1843 if (vp->v_type == VDIR) 1844 error = EPERM; /* POSIX */ 1845 else { 1846 /* 1847 * The root of a mounted filesystem cannot be deleted. 1848 * 1849 * XXX: can this only be a VDIR case? 1850 */ 1851 if (vp->v_vflag & VV_ROOT) 1852 error = EBUSY; 1853 } 1854 if (error == 0) { 1855 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1856 NDFREE(&nd, NDF_ONLY_PNBUF); 1857 vput(nd.ni_dvp); 1858 if (vp == nd.ni_dvp) 1859 vrele(vp); 1860 else 1861 vput(vp); 1862 VFS_UNLOCK_GIANT(vfslocked); 1863 if ((error = vn_start_write(NULL, &mp, 1864 V_XSLEEP | PCATCH)) != 0) 1865 return (error); 1866 goto restart; 1867 } 1868 #ifdef MAC 1869 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 1870 &nd.ni_cnd); 1871 if (error) 1872 goto out; 1873 #endif 1874 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1875 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1876 #ifdef MAC 1877 out: 1878 #endif 1879 vn_finished_write(mp); 1880 } 1881 NDFREE(&nd, NDF_ONLY_PNBUF); 1882 vput(nd.ni_dvp); 1883 if (vp == nd.ni_dvp) 1884 vrele(vp); 1885 else 1886 vput(vp); 1887 VFS_UNLOCK_GIANT(vfslocked); 1888 return (error); 1889 } 1890 1891 /* 1892 * Reposition read/write file offset. 1893 */ 1894 #ifndef _SYS_SYSPROTO_H_ 1895 struct lseek_args { 1896 int fd; 1897 int pad; 1898 off_t offset; 1899 int whence; 1900 }; 1901 #endif 1902 int 1903 lseek(td, uap) 1904 struct thread *td; 1905 register struct lseek_args /* { 1906 int fd; 1907 int pad; 1908 off_t offset; 1909 int whence; 1910 } */ *uap; 1911 { 1912 struct ucred *cred = td->td_ucred; 1913 struct file *fp; 1914 struct vnode *vp; 1915 struct vattr vattr; 1916 off_t offset; 1917 int error, noneg; 1918 int vfslocked; 1919 1920 if ((error = fget(td, uap->fd, &fp)) != 0) 1921 return (error); 1922 if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { 1923 fdrop(fp, td); 1924 return (ESPIPE); 1925 } 1926 vp = fp->f_vnode; 1927 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 1928 noneg = (vp->v_type != VCHR); 1929 offset = uap->offset; 1930 switch (uap->whence) { 1931 case L_INCR: 1932 if (noneg && 1933 (fp->f_offset < 0 || 1934 (offset > 0 && fp->f_offset > OFF_MAX - offset))) { 1935 error = EOVERFLOW; 1936 break; 1937 } 1938 offset += fp->f_offset; 1939 break; 1940 case L_XTND: 1941 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1942 error = VOP_GETATTR(vp, &vattr, cred); 1943 VOP_UNLOCK(vp, 0); 1944 if (error) 1945 break; 1946 if (noneg && 1947 (vattr.va_size > OFF_MAX || 1948 (offset > 0 && vattr.va_size > OFF_MAX - offset))) { 1949 error = EOVERFLOW; 1950 break; 1951 } 1952 offset += vattr.va_size; 1953 break; 1954 case L_SET: 1955 break; 1956 case SEEK_DATA: 1957 error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td); 1958 break; 1959 case SEEK_HOLE: 1960 error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td); 1961 break; 1962 default: 1963 error = EINVAL; 1964 } 1965 if (error == 0 && noneg && offset < 0) 1966 error = EINVAL; 1967 if (error != 0) 1968 goto drop; 1969 fp->f_offset = offset; 1970 *(off_t *)(td->td_retval) = fp->f_offset; 1971 drop: 1972 fdrop(fp, td); 1973 VFS_UNLOCK_GIANT(vfslocked); 1974 return (error); 1975 } 1976 1977 #if defined(COMPAT_43) 1978 /* 1979 * Reposition read/write file offset. 1980 */ 1981 #ifndef _SYS_SYSPROTO_H_ 1982 struct olseek_args { 1983 int fd; 1984 long offset; 1985 int whence; 1986 }; 1987 #endif 1988 int 1989 olseek(td, uap) 1990 struct thread *td; 1991 register struct olseek_args /* { 1992 int fd; 1993 long offset; 1994 int whence; 1995 } */ *uap; 1996 { 1997 struct lseek_args /* { 1998 int fd; 1999 int pad; 2000 off_t offset; 2001 int whence; 2002 } */ nuap; 2003 2004 nuap.fd = uap->fd; 2005 nuap.offset = uap->offset; 2006 nuap.whence = uap->whence; 2007 return (lseek(td, &nuap)); 2008 } 2009 #endif /* COMPAT_43 */ 2010 2011 /* Version with the 'pad' argument */ 2012 int 2013 freebsd6_lseek(td, uap) 2014 struct thread *td; 2015 register struct freebsd6_lseek_args *uap; 2016 { 2017 struct lseek_args ouap; 2018 2019 ouap.fd = uap->fd; 2020 ouap.offset = uap->offset; 2021 ouap.whence = uap->whence; 2022 return (lseek(td, &ouap)); 2023 } 2024 2025 /* 2026 * Check access permissions using passed credentials. 2027 */ 2028 static int 2029 vn_access(vp, user_flags, cred, td) 2030 struct vnode *vp; 2031 int user_flags; 2032 struct ucred *cred; 2033 struct thread *td; 2034 { 2035 int error, flags; 2036 2037 /* Flags == 0 means only check for existence. */ 2038 error = 0; 2039 if (user_flags) { 2040 flags = 0; 2041 if (user_flags & R_OK) 2042 flags |= VREAD; 2043 if (user_flags & W_OK) 2044 flags |= VWRITE; 2045 if (user_flags & X_OK) 2046 flags |= VEXEC; 2047 #ifdef MAC 2048 error = mac_vnode_check_access(cred, vp, flags); 2049 if (error) 2050 return (error); 2051 #endif 2052 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 2053 error = VOP_ACCESS(vp, flags, cred, td); 2054 } 2055 return (error); 2056 } 2057 2058 /* 2059 * Check access permissions using "real" credentials. 2060 */ 2061 #ifndef _SYS_SYSPROTO_H_ 2062 struct access_args { 2063 char *path; 2064 int flags; 2065 }; 2066 #endif 2067 int 2068 access(td, uap) 2069 struct thread *td; 2070 register struct access_args /* { 2071 char *path; 2072 int flags; 2073 } */ *uap; 2074 { 2075 2076 return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags)); 2077 } 2078 2079 #ifndef _SYS_SYSPROTO_H_ 2080 struct faccessat_args { 2081 int dirfd; 2082 char *path; 2083 int mode; 2084 int flag; 2085 } 2086 #endif 2087 int 2088 faccessat(struct thread *td, struct faccessat_args *uap) 2089 { 2090 2091 if (uap->flag & ~AT_EACCESS) 2092 return (EINVAL); 2093 return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, 2094 uap->mode)); 2095 } 2096 2097 int 2098 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2099 { 2100 2101 return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, mode)); 2102 } 2103 2104 int 2105 kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2106 int flags, int mode) 2107 { 2108 struct ucred *cred, *tmpcred; 2109 struct vnode *vp; 2110 struct nameidata nd; 2111 int vfslocked; 2112 int error; 2113 2114 /* 2115 * Create and modify a temporary credential instead of one that 2116 * is potentially shared. This could also mess up socket 2117 * buffer accounting which can run in an interrupt context. 2118 */ 2119 if (!(flags & AT_EACCESS)) { 2120 cred = td->td_ucred; 2121 tmpcred = crdup(cred); 2122 tmpcred->cr_uid = cred->cr_ruid; 2123 tmpcred->cr_groups[0] = cred->cr_rgid; 2124 td->td_ucred = tmpcred; 2125 } else 2126 cred = tmpcred = td->td_ucred; 2127 NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2128 pathseg, path, fd, td); 2129 if ((error = namei(&nd)) != 0) 2130 goto out1; 2131 vfslocked = NDHASGIANT(&nd); 2132 vp = nd.ni_vp; 2133 2134 error = vn_access(vp, mode, tmpcred, td); 2135 NDFREE(&nd, NDF_ONLY_PNBUF); 2136 vput(vp); 2137 VFS_UNLOCK_GIANT(vfslocked); 2138 out1: 2139 if (!(flags & AT_EACCESS)) { 2140 td->td_ucred = cred; 2141 crfree(tmpcred); 2142 } 2143 return (error); 2144 } 2145 2146 /* 2147 * Check access permissions using "effective" credentials. 2148 */ 2149 #ifndef _SYS_SYSPROTO_H_ 2150 struct eaccess_args { 2151 char *path; 2152 int flags; 2153 }; 2154 #endif 2155 int 2156 eaccess(td, uap) 2157 struct thread *td; 2158 register struct eaccess_args /* { 2159 char *path; 2160 int flags; 2161 } */ *uap; 2162 { 2163 2164 return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags)); 2165 } 2166 2167 int 2168 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags) 2169 { 2170 2171 return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, flags)); 2172 } 2173 2174 #if defined(COMPAT_43) 2175 /* 2176 * Get file status; this version follows links. 2177 */ 2178 #ifndef _SYS_SYSPROTO_H_ 2179 struct ostat_args { 2180 char *path; 2181 struct ostat *ub; 2182 }; 2183 #endif 2184 int 2185 ostat(td, uap) 2186 struct thread *td; 2187 register struct ostat_args /* { 2188 char *path; 2189 struct ostat *ub; 2190 } */ *uap; 2191 { 2192 struct stat sb; 2193 struct ostat osb; 2194 int error; 2195 2196 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2197 if (error) 2198 return (error); 2199 cvtstat(&sb, &osb); 2200 error = copyout(&osb, uap->ub, sizeof (osb)); 2201 return (error); 2202 } 2203 2204 /* 2205 * Get file status; this version does not follow links. 2206 */ 2207 #ifndef _SYS_SYSPROTO_H_ 2208 struct olstat_args { 2209 char *path; 2210 struct ostat *ub; 2211 }; 2212 #endif 2213 int 2214 olstat(td, uap) 2215 struct thread *td; 2216 register struct olstat_args /* { 2217 char *path; 2218 struct ostat *ub; 2219 } */ *uap; 2220 { 2221 struct stat sb; 2222 struct ostat osb; 2223 int error; 2224 2225 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2226 if (error) 2227 return (error); 2228 cvtstat(&sb, &osb); 2229 error = copyout(&osb, uap->ub, sizeof (osb)); 2230 return (error); 2231 } 2232 2233 /* 2234 * Convert from an old to a new stat structure. 2235 */ 2236 void 2237 cvtstat(st, ost) 2238 struct stat *st; 2239 struct ostat *ost; 2240 { 2241 2242 ost->st_dev = st->st_dev; 2243 ost->st_ino = st->st_ino; 2244 ost->st_mode = st->st_mode; 2245 ost->st_nlink = st->st_nlink; 2246 ost->st_uid = st->st_uid; 2247 ost->st_gid = st->st_gid; 2248 ost->st_rdev = st->st_rdev; 2249 if (st->st_size < (quad_t)1 << 32) 2250 ost->st_size = st->st_size; 2251 else 2252 ost->st_size = -2; 2253 ost->st_atime = st->st_atime; 2254 ost->st_mtime = st->st_mtime; 2255 ost->st_ctime = st->st_ctime; 2256 ost->st_blksize = st->st_blksize; 2257 ost->st_blocks = st->st_blocks; 2258 ost->st_flags = st->st_flags; 2259 ost->st_gen = st->st_gen; 2260 } 2261 #endif /* COMPAT_43 */ 2262 2263 /* 2264 * Get file status; this version follows links. 2265 */ 2266 #ifndef _SYS_SYSPROTO_H_ 2267 struct stat_args { 2268 char *path; 2269 struct stat *ub; 2270 }; 2271 #endif 2272 int 2273 stat(td, uap) 2274 struct thread *td; 2275 register struct stat_args /* { 2276 char *path; 2277 struct stat *ub; 2278 } */ *uap; 2279 { 2280 struct stat sb; 2281 int error; 2282 2283 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2284 if (error == 0) 2285 error = copyout(&sb, uap->ub, sizeof (sb)); 2286 return (error); 2287 } 2288 2289 #ifndef _SYS_SYSPROTO_H_ 2290 struct fstatat_args { 2291 int fd; 2292 char *path; 2293 struct stat *buf; 2294 int flag; 2295 } 2296 #endif 2297 int 2298 fstatat(struct thread *td, struct fstatat_args *uap) 2299 { 2300 struct stat sb; 2301 int error; 2302 2303 error = kern_statat(td, uap->flag, uap->fd, uap->path, 2304 UIO_USERSPACE, &sb); 2305 if (error == 0) 2306 error = copyout(&sb, uap->buf, sizeof (sb)); 2307 return (error); 2308 } 2309 2310 int 2311 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2312 { 2313 2314 return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); 2315 } 2316 2317 int 2318 kern_statat(struct thread *td, int flag, int fd, char *path, 2319 enum uio_seg pathseg, struct stat *sbp) 2320 { 2321 struct nameidata nd; 2322 struct stat sb; 2323 int error, vfslocked; 2324 2325 if (flag & ~AT_SYMLINK_NOFOLLOW) 2326 return (EINVAL); 2327 2328 NDINIT_AT(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : 2329 FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, 2330 path, fd, td); 2331 2332 if ((error = namei(&nd)) != 0) 2333 return (error); 2334 vfslocked = NDHASGIANT(&nd); 2335 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 2336 NDFREE(&nd, NDF_ONLY_PNBUF); 2337 vput(nd.ni_vp); 2338 VFS_UNLOCK_GIANT(vfslocked); 2339 if (mtx_owned(&Giant)) 2340 printf("stat(%d): %s\n", vfslocked, path); 2341 if (error) 2342 return (error); 2343 *sbp = sb; 2344 #ifdef KTRACE 2345 if (KTRPOINT(td, KTR_STRUCT)) 2346 ktrstat(&sb); 2347 #endif 2348 return (0); 2349 } 2350 2351 /* 2352 * Get file status; this version does not follow links. 2353 */ 2354 #ifndef _SYS_SYSPROTO_H_ 2355 struct lstat_args { 2356 char *path; 2357 struct stat *ub; 2358 }; 2359 #endif 2360 int 2361 lstat(td, uap) 2362 struct thread *td; 2363 register struct lstat_args /* { 2364 char *path; 2365 struct stat *ub; 2366 } */ *uap; 2367 { 2368 struct stat sb; 2369 int error; 2370 2371 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2372 if (error == 0) 2373 error = copyout(&sb, uap->ub, sizeof (sb)); 2374 return (error); 2375 } 2376 2377 int 2378 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2379 { 2380 2381 return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, 2382 sbp)); 2383 } 2384 2385 /* 2386 * Implementation of the NetBSD [l]stat() functions. 2387 */ 2388 void 2389 cvtnstat(sb, nsb) 2390 struct stat *sb; 2391 struct nstat *nsb; 2392 { 2393 bzero(nsb, sizeof *nsb); 2394 nsb->st_dev = sb->st_dev; 2395 nsb->st_ino = sb->st_ino; 2396 nsb->st_mode = sb->st_mode; 2397 nsb->st_nlink = sb->st_nlink; 2398 nsb->st_uid = sb->st_uid; 2399 nsb->st_gid = sb->st_gid; 2400 nsb->st_rdev = sb->st_rdev; 2401 nsb->st_atimespec = sb->st_atimespec; 2402 nsb->st_mtimespec = sb->st_mtimespec; 2403 nsb->st_ctimespec = sb->st_ctimespec; 2404 nsb->st_size = sb->st_size; 2405 nsb->st_blocks = sb->st_blocks; 2406 nsb->st_blksize = sb->st_blksize; 2407 nsb->st_flags = sb->st_flags; 2408 nsb->st_gen = sb->st_gen; 2409 nsb->st_birthtimespec = sb->st_birthtimespec; 2410 } 2411 2412 #ifndef _SYS_SYSPROTO_H_ 2413 struct nstat_args { 2414 char *path; 2415 struct nstat *ub; 2416 }; 2417 #endif 2418 int 2419 nstat(td, uap) 2420 struct thread *td; 2421 register struct nstat_args /* { 2422 char *path; 2423 struct nstat *ub; 2424 } */ *uap; 2425 { 2426 struct stat sb; 2427 struct nstat nsb; 2428 int error; 2429 2430 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2431 if (error) 2432 return (error); 2433 cvtnstat(&sb, &nsb); 2434 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2435 return (error); 2436 } 2437 2438 /* 2439 * NetBSD lstat. Get file status; this version does not follow links. 2440 */ 2441 #ifndef _SYS_SYSPROTO_H_ 2442 struct lstat_args { 2443 char *path; 2444 struct stat *ub; 2445 }; 2446 #endif 2447 int 2448 nlstat(td, uap) 2449 struct thread *td; 2450 register struct nlstat_args /* { 2451 char *path; 2452 struct nstat *ub; 2453 } */ *uap; 2454 { 2455 struct stat sb; 2456 struct nstat nsb; 2457 int error; 2458 2459 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2460 if (error) 2461 return (error); 2462 cvtnstat(&sb, &nsb); 2463 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2464 return (error); 2465 } 2466 2467 /* 2468 * Get configurable pathname variables. 2469 */ 2470 #ifndef _SYS_SYSPROTO_H_ 2471 struct pathconf_args { 2472 char *path; 2473 int name; 2474 }; 2475 #endif 2476 int 2477 pathconf(td, uap) 2478 struct thread *td; 2479 register struct pathconf_args /* { 2480 char *path; 2481 int name; 2482 } */ *uap; 2483 { 2484 2485 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name)); 2486 } 2487 2488 int 2489 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name) 2490 { 2491 struct nameidata nd; 2492 int error, vfslocked; 2493 2494 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2495 pathseg, path, td); 2496 if ((error = namei(&nd)) != 0) 2497 return (error); 2498 vfslocked = NDHASGIANT(&nd); 2499 NDFREE(&nd, NDF_ONLY_PNBUF); 2500 2501 /* If asynchronous I/O is available, it works for all files. */ 2502 if (name == _PC_ASYNC_IO) 2503 td->td_retval[0] = async_io_version; 2504 else 2505 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval); 2506 vput(nd.ni_vp); 2507 VFS_UNLOCK_GIANT(vfslocked); 2508 return (error); 2509 } 2510 2511 /* 2512 * Return target name of a symbolic link. 2513 */ 2514 #ifndef _SYS_SYSPROTO_H_ 2515 struct readlink_args { 2516 char *path; 2517 char *buf; 2518 size_t count; 2519 }; 2520 #endif 2521 int 2522 readlink(td, uap) 2523 struct thread *td; 2524 register struct readlink_args /* { 2525 char *path; 2526 char *buf; 2527 size_t count; 2528 } */ *uap; 2529 { 2530 2531 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, 2532 UIO_USERSPACE, uap->count)); 2533 } 2534 #ifndef _SYS_SYSPROTO_H_ 2535 struct readlinkat_args { 2536 int fd; 2537 char *path; 2538 char *buf; 2539 size_t bufsize; 2540 }; 2541 #endif 2542 int 2543 readlinkat(struct thread *td, struct readlinkat_args *uap) 2544 { 2545 2546 return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, 2547 uap->buf, UIO_USERSPACE, uap->bufsize)); 2548 } 2549 2550 int 2551 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, 2552 enum uio_seg bufseg, size_t count) 2553 { 2554 2555 return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, 2556 count)); 2557 } 2558 2559 int 2560 kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2561 char *buf, enum uio_seg bufseg, size_t count) 2562 { 2563 struct vnode *vp; 2564 struct iovec aiov; 2565 struct uio auio; 2566 int error; 2567 struct nameidata nd; 2568 int vfslocked; 2569 2570 NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2571 pathseg, path, fd, td); 2572 2573 if ((error = namei(&nd)) != 0) 2574 return (error); 2575 NDFREE(&nd, NDF_ONLY_PNBUF); 2576 vfslocked = NDHASGIANT(&nd); 2577 vp = nd.ni_vp; 2578 #ifdef MAC 2579 error = mac_vnode_check_readlink(td->td_ucred, vp); 2580 if (error) { 2581 vput(vp); 2582 VFS_UNLOCK_GIANT(vfslocked); 2583 return (error); 2584 } 2585 #endif 2586 if (vp->v_type != VLNK) 2587 error = EINVAL; 2588 else { 2589 aiov.iov_base = buf; 2590 aiov.iov_len = count; 2591 auio.uio_iov = &aiov; 2592 auio.uio_iovcnt = 1; 2593 auio.uio_offset = 0; 2594 auio.uio_rw = UIO_READ; 2595 auio.uio_segflg = bufseg; 2596 auio.uio_td = td; 2597 auio.uio_resid = count; 2598 error = VOP_READLINK(vp, &auio, td->td_ucred); 2599 } 2600 vput(vp); 2601 VFS_UNLOCK_GIANT(vfslocked); 2602 td->td_retval[0] = count - auio.uio_resid; 2603 return (error); 2604 } 2605 2606 /* 2607 * Common implementation code for chflags() and fchflags(). 2608 */ 2609 static int 2610 setfflags(td, vp, flags) 2611 struct thread *td; 2612 struct vnode *vp; 2613 int flags; 2614 { 2615 int error; 2616 struct mount *mp; 2617 struct vattr vattr; 2618 2619 /* 2620 * Prevent non-root users from setting flags on devices. When 2621 * a device is reused, users can retain ownership of the device 2622 * if they are allowed to set flags and programs assume that 2623 * chown can't fail when done as root. 2624 */ 2625 if (vp->v_type == VCHR || vp->v_type == VBLK) { 2626 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); 2627 if (error) 2628 return (error); 2629 } 2630 2631 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2632 return (error); 2633 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2634 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2635 VATTR_NULL(&vattr); 2636 vattr.va_flags = flags; 2637 #ifdef MAC 2638 error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); 2639 if (error == 0) 2640 #endif 2641 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2642 VOP_UNLOCK(vp, 0); 2643 vn_finished_write(mp); 2644 return (error); 2645 } 2646 2647 /* 2648 * Change flags of a file given a path name. 2649 */ 2650 #ifndef _SYS_SYSPROTO_H_ 2651 struct chflags_args { 2652 char *path; 2653 int flags; 2654 }; 2655 #endif 2656 int 2657 chflags(td, uap) 2658 struct thread *td; 2659 register struct chflags_args /* { 2660 char *path; 2661 int flags; 2662 } */ *uap; 2663 { 2664 int error; 2665 struct nameidata nd; 2666 int vfslocked; 2667 2668 AUDIT_ARG(fflags, uap->flags); 2669 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2670 uap->path, td); 2671 if ((error = namei(&nd)) != 0) 2672 return (error); 2673 NDFREE(&nd, NDF_ONLY_PNBUF); 2674 vfslocked = NDHASGIANT(&nd); 2675 error = setfflags(td, nd.ni_vp, uap->flags); 2676 vrele(nd.ni_vp); 2677 VFS_UNLOCK_GIANT(vfslocked); 2678 return (error); 2679 } 2680 2681 /* 2682 * Same as chflags() but doesn't follow symlinks. 2683 */ 2684 int 2685 lchflags(td, uap) 2686 struct thread *td; 2687 register struct lchflags_args /* { 2688 char *path; 2689 int flags; 2690 } */ *uap; 2691 { 2692 int error; 2693 struct nameidata nd; 2694 int vfslocked; 2695 2696 AUDIT_ARG(fflags, uap->flags); 2697 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2698 uap->path, td); 2699 if ((error = namei(&nd)) != 0) 2700 return (error); 2701 vfslocked = NDHASGIANT(&nd); 2702 NDFREE(&nd, NDF_ONLY_PNBUF); 2703 error = setfflags(td, nd.ni_vp, uap->flags); 2704 vrele(nd.ni_vp); 2705 VFS_UNLOCK_GIANT(vfslocked); 2706 return (error); 2707 } 2708 2709 /* 2710 * Change flags of a file given a file descriptor. 2711 */ 2712 #ifndef _SYS_SYSPROTO_H_ 2713 struct fchflags_args { 2714 int fd; 2715 int flags; 2716 }; 2717 #endif 2718 int 2719 fchflags(td, uap) 2720 struct thread *td; 2721 register struct fchflags_args /* { 2722 int fd; 2723 int flags; 2724 } */ *uap; 2725 { 2726 struct file *fp; 2727 int vfslocked; 2728 int error; 2729 2730 AUDIT_ARG(fd, uap->fd); 2731 AUDIT_ARG(fflags, uap->flags); 2732 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2733 return (error); 2734 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2735 #ifdef AUDIT 2736 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 2737 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2738 VOP_UNLOCK(fp->f_vnode, 0); 2739 #endif 2740 error = setfflags(td, fp->f_vnode, uap->flags); 2741 VFS_UNLOCK_GIANT(vfslocked); 2742 fdrop(fp, td); 2743 return (error); 2744 } 2745 2746 /* 2747 * Common implementation code for chmod(), lchmod() and fchmod(). 2748 */ 2749 static int 2750 setfmode(td, vp, mode) 2751 struct thread *td; 2752 struct vnode *vp; 2753 int mode; 2754 { 2755 int error; 2756 struct mount *mp; 2757 struct vattr vattr; 2758 2759 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2760 return (error); 2761 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2762 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2763 VATTR_NULL(&vattr); 2764 vattr.va_mode = mode & ALLPERMS; 2765 #ifdef MAC 2766 error = mac_vnode_check_setmode(td->td_ucred, vp, vattr.va_mode); 2767 if (error == 0) 2768 #endif 2769 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2770 VOP_UNLOCK(vp, 0); 2771 vn_finished_write(mp); 2772 return (error); 2773 } 2774 2775 /* 2776 * Change mode of a file given path name. 2777 */ 2778 #ifndef _SYS_SYSPROTO_H_ 2779 struct chmod_args { 2780 char *path; 2781 int mode; 2782 }; 2783 #endif 2784 int 2785 chmod(td, uap) 2786 struct thread *td; 2787 register struct chmod_args /* { 2788 char *path; 2789 int mode; 2790 } */ *uap; 2791 { 2792 2793 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); 2794 } 2795 2796 #ifndef _SYS_SYSPROTO_H_ 2797 struct fchmodat_args { 2798 int dirfd; 2799 char *path; 2800 mode_t mode; 2801 int flag; 2802 } 2803 #endif 2804 int 2805 fchmodat(struct thread *td, struct fchmodat_args *uap) 2806 { 2807 int flag = uap->flag; 2808 int fd = uap->fd; 2809 char *path = uap->path; 2810 mode_t mode = uap->mode; 2811 2812 if (flag & ~AT_SYMLINK_NOFOLLOW) 2813 return (EINVAL); 2814 2815 return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); 2816 } 2817 2818 int 2819 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2820 { 2821 2822 return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); 2823 } 2824 2825 /* 2826 * Change mode of a file given path name (don't follow links.) 2827 */ 2828 #ifndef _SYS_SYSPROTO_H_ 2829 struct lchmod_args { 2830 char *path; 2831 int mode; 2832 }; 2833 #endif 2834 int 2835 lchmod(td, uap) 2836 struct thread *td; 2837 register struct lchmod_args /* { 2838 char *path; 2839 int mode; 2840 } */ *uap; 2841 { 2842 2843 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 2844 uap->mode, AT_SYMLINK_NOFOLLOW)); 2845 } 2846 2847 2848 int 2849 kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2850 mode_t mode, int flag) 2851 { 2852 int error; 2853 struct nameidata nd; 2854 int vfslocked; 2855 int follow; 2856 2857 AUDIT_ARG(mode, mode); 2858 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 2859 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 2860 fd, td); 2861 if ((error = namei(&nd)) != 0) 2862 return (error); 2863 vfslocked = NDHASGIANT(&nd); 2864 NDFREE(&nd, NDF_ONLY_PNBUF); 2865 error = setfmode(td, nd.ni_vp, mode); 2866 vrele(nd.ni_vp); 2867 VFS_UNLOCK_GIANT(vfslocked); 2868 return (error); 2869 } 2870 2871 /* 2872 * Change mode of a file given a file descriptor. 2873 */ 2874 #ifndef _SYS_SYSPROTO_H_ 2875 struct fchmod_args { 2876 int fd; 2877 int mode; 2878 }; 2879 #endif 2880 int 2881 fchmod(td, uap) 2882 struct thread *td; 2883 register struct fchmod_args /* { 2884 int fd; 2885 int mode; 2886 } */ *uap; 2887 { 2888 struct file *fp; 2889 int vfslocked; 2890 int error; 2891 2892 AUDIT_ARG(fd, uap->fd); 2893 AUDIT_ARG(mode, uap->mode); 2894 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2895 return (error); 2896 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2897 #ifdef AUDIT 2898 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 2899 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2900 VOP_UNLOCK(fp->f_vnode, 0); 2901 #endif 2902 error = setfmode(td, fp->f_vnode, uap->mode); 2903 VFS_UNLOCK_GIANT(vfslocked); 2904 fdrop(fp, td); 2905 return (error); 2906 } 2907 2908 /* 2909 * Common implementation for chown(), lchown(), and fchown() 2910 */ 2911 static int 2912 setfown(td, vp, uid, gid) 2913 struct thread *td; 2914 struct vnode *vp; 2915 uid_t uid; 2916 gid_t gid; 2917 { 2918 int error; 2919 struct mount *mp; 2920 struct vattr vattr; 2921 2922 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2923 return (error); 2924 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2925 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2926 VATTR_NULL(&vattr); 2927 vattr.va_uid = uid; 2928 vattr.va_gid = gid; 2929 #ifdef MAC 2930 error = mac_vnode_check_setowner(td->td_ucred, vp, vattr.va_uid, 2931 vattr.va_gid); 2932 if (error == 0) 2933 #endif 2934 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2935 VOP_UNLOCK(vp, 0); 2936 vn_finished_write(mp); 2937 return (error); 2938 } 2939 2940 /* 2941 * Set ownership given a path name. 2942 */ 2943 #ifndef _SYS_SYSPROTO_H_ 2944 struct chown_args { 2945 char *path; 2946 int uid; 2947 int gid; 2948 }; 2949 #endif 2950 int 2951 chown(td, uap) 2952 struct thread *td; 2953 register struct chown_args /* { 2954 char *path; 2955 int uid; 2956 int gid; 2957 } */ *uap; 2958 { 2959 2960 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 2961 } 2962 2963 #ifndef _SYS_SYSPROTO_H_ 2964 struct fchownat_args { 2965 int fd; 2966 const char * path; 2967 uid_t uid; 2968 gid_t gid; 2969 int flag; 2970 }; 2971 #endif 2972 int 2973 fchownat(struct thread *td, struct fchownat_args *uap) 2974 { 2975 int flag; 2976 2977 flag = uap->flag; 2978 if (flag & ~AT_SYMLINK_NOFOLLOW) 2979 return (EINVAL); 2980 2981 return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, 2982 uap->gid, uap->flag)); 2983 } 2984 2985 int 2986 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 2987 int gid) 2988 { 2989 2990 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); 2991 } 2992 2993 int 2994 kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2995 int uid, int gid, int flag) 2996 { 2997 struct nameidata nd; 2998 int error, vfslocked, follow; 2999 3000 AUDIT_ARG(owner, uid, gid); 3001 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 3002 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 3003 fd, td); 3004 3005 if ((error = namei(&nd)) != 0) 3006 return (error); 3007 vfslocked = NDHASGIANT(&nd); 3008 NDFREE(&nd, NDF_ONLY_PNBUF); 3009 error = setfown(td, nd.ni_vp, uid, gid); 3010 vrele(nd.ni_vp); 3011 VFS_UNLOCK_GIANT(vfslocked); 3012 return (error); 3013 } 3014 3015 /* 3016 * Set ownership given a path name, do not cross symlinks. 3017 */ 3018 #ifndef _SYS_SYSPROTO_H_ 3019 struct lchown_args { 3020 char *path; 3021 int uid; 3022 int gid; 3023 }; 3024 #endif 3025 int 3026 lchown(td, uap) 3027 struct thread *td; 3028 register struct lchown_args /* { 3029 char *path; 3030 int uid; 3031 int gid; 3032 } */ *uap; 3033 { 3034 3035 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 3036 } 3037 3038 int 3039 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3040 int gid) 3041 { 3042 3043 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 3044 AT_SYMLINK_NOFOLLOW)); 3045 } 3046 3047 /* 3048 * Set ownership given a file descriptor. 3049 */ 3050 #ifndef _SYS_SYSPROTO_H_ 3051 struct fchown_args { 3052 int fd; 3053 int uid; 3054 int gid; 3055 }; 3056 #endif 3057 int 3058 fchown(td, uap) 3059 struct thread *td; 3060 register struct fchown_args /* { 3061 int fd; 3062 int uid; 3063 int gid; 3064 } */ *uap; 3065 { 3066 struct file *fp; 3067 int vfslocked; 3068 int error; 3069 3070 AUDIT_ARG(fd, uap->fd); 3071 AUDIT_ARG(owner, uap->uid, uap->gid); 3072 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3073 return (error); 3074 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3075 #ifdef AUDIT 3076 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 3077 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3078 VOP_UNLOCK(fp->f_vnode, 0); 3079 #endif 3080 error = setfown(td, fp->f_vnode, uap->uid, uap->gid); 3081 VFS_UNLOCK_GIANT(vfslocked); 3082 fdrop(fp, td); 3083 return (error); 3084 } 3085 3086 /* 3087 * Common implementation code for utimes(), lutimes(), and futimes(). 3088 */ 3089 static int 3090 getutimes(usrtvp, tvpseg, tsp) 3091 const struct timeval *usrtvp; 3092 enum uio_seg tvpseg; 3093 struct timespec *tsp; 3094 { 3095 struct timeval tv[2]; 3096 const struct timeval *tvp; 3097 int error; 3098 3099 if (usrtvp == NULL) { 3100 microtime(&tv[0]); 3101 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 3102 tsp[1] = tsp[0]; 3103 } else { 3104 if (tvpseg == UIO_SYSSPACE) { 3105 tvp = usrtvp; 3106 } else { 3107 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) 3108 return (error); 3109 tvp = tv; 3110 } 3111 3112 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || 3113 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) 3114 return (EINVAL); 3115 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 3116 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 3117 } 3118 return (0); 3119 } 3120 3121 /* 3122 * Common implementation code for utimes(), lutimes(), and futimes(). 3123 */ 3124 static int 3125 setutimes(td, vp, ts, numtimes, nullflag) 3126 struct thread *td; 3127 struct vnode *vp; 3128 const struct timespec *ts; 3129 int numtimes; 3130 int nullflag; 3131 { 3132 int error, setbirthtime; 3133 struct mount *mp; 3134 struct vattr vattr; 3135 3136 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3137 return (error); 3138 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3139 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3140 setbirthtime = 0; 3141 if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && 3142 timespeccmp(&ts[1], &vattr.va_birthtime, < )) 3143 setbirthtime = 1; 3144 VATTR_NULL(&vattr); 3145 vattr.va_atime = ts[0]; 3146 vattr.va_mtime = ts[1]; 3147 if (setbirthtime) 3148 vattr.va_birthtime = ts[1]; 3149 if (numtimes > 2) 3150 vattr.va_birthtime = ts[2]; 3151 if (nullflag) 3152 vattr.va_vaflags |= VA_UTIMES_NULL; 3153 #ifdef MAC 3154 error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, 3155 vattr.va_mtime); 3156 #endif 3157 if (error == 0) 3158 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3159 VOP_UNLOCK(vp, 0); 3160 vn_finished_write(mp); 3161 return (error); 3162 } 3163 3164 /* 3165 * Set the access and modification times of a file. 3166 */ 3167 #ifndef _SYS_SYSPROTO_H_ 3168 struct utimes_args { 3169 char *path; 3170 struct timeval *tptr; 3171 }; 3172 #endif 3173 int 3174 utimes(td, uap) 3175 struct thread *td; 3176 register struct utimes_args /* { 3177 char *path; 3178 struct timeval *tptr; 3179 } */ *uap; 3180 { 3181 3182 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3183 UIO_USERSPACE)); 3184 } 3185 3186 #ifndef _SYS_SYSPROTO_H_ 3187 struct futimesat_args { 3188 int fd; 3189 const char * path; 3190 const struct timeval * times; 3191 }; 3192 #endif 3193 int 3194 futimesat(struct thread *td, struct futimesat_args *uap) 3195 { 3196 3197 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 3198 uap->times, UIO_USERSPACE)); 3199 } 3200 3201 int 3202 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, 3203 struct timeval *tptr, enum uio_seg tptrseg) 3204 { 3205 3206 return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); 3207 } 3208 3209 int 3210 kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3211 struct timeval *tptr, enum uio_seg tptrseg) 3212 { 3213 struct nameidata nd; 3214 struct timespec ts[2]; 3215 int error, vfslocked; 3216 3217 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3218 return (error); 3219 NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, 3220 fd, td); 3221 3222 if ((error = namei(&nd)) != 0) 3223 return (error); 3224 vfslocked = NDHASGIANT(&nd); 3225 NDFREE(&nd, NDF_ONLY_PNBUF); 3226 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3227 vrele(nd.ni_vp); 3228 VFS_UNLOCK_GIANT(vfslocked); 3229 return (error); 3230 } 3231 3232 /* 3233 * Set the access and modification times of a file. 3234 */ 3235 #ifndef _SYS_SYSPROTO_H_ 3236 struct lutimes_args { 3237 char *path; 3238 struct timeval *tptr; 3239 }; 3240 #endif 3241 int 3242 lutimes(td, uap) 3243 struct thread *td; 3244 register struct lutimes_args /* { 3245 char *path; 3246 struct timeval *tptr; 3247 } */ *uap; 3248 { 3249 3250 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3251 UIO_USERSPACE)); 3252 } 3253 3254 int 3255 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, 3256 struct timeval *tptr, enum uio_seg tptrseg) 3257 { 3258 struct timespec ts[2]; 3259 int error; 3260 struct nameidata nd; 3261 int vfslocked; 3262 3263 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3264 return (error); 3265 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3266 if ((error = namei(&nd)) != 0) 3267 return (error); 3268 vfslocked = NDHASGIANT(&nd); 3269 NDFREE(&nd, NDF_ONLY_PNBUF); 3270 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3271 vrele(nd.ni_vp); 3272 VFS_UNLOCK_GIANT(vfslocked); 3273 return (error); 3274 } 3275 3276 /* 3277 * Set the access and modification times of a file. 3278 */ 3279 #ifndef _SYS_SYSPROTO_H_ 3280 struct futimes_args { 3281 int fd; 3282 struct timeval *tptr; 3283 }; 3284 #endif 3285 int 3286 futimes(td, uap) 3287 struct thread *td; 3288 register struct futimes_args /* { 3289 int fd; 3290 struct timeval *tptr; 3291 } */ *uap; 3292 { 3293 3294 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); 3295 } 3296 3297 int 3298 kern_futimes(struct thread *td, int fd, struct timeval *tptr, 3299 enum uio_seg tptrseg) 3300 { 3301 struct timespec ts[2]; 3302 struct file *fp; 3303 int vfslocked; 3304 int error; 3305 3306 AUDIT_ARG(fd, fd); 3307 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3308 return (error); 3309 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 3310 return (error); 3311 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3312 #ifdef AUDIT 3313 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 3314 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3315 VOP_UNLOCK(fp->f_vnode, 0); 3316 #endif 3317 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); 3318 VFS_UNLOCK_GIANT(vfslocked); 3319 fdrop(fp, td); 3320 return (error); 3321 } 3322 3323 /* 3324 * Truncate a file given its path name. 3325 */ 3326 #ifndef _SYS_SYSPROTO_H_ 3327 struct truncate_args { 3328 char *path; 3329 int pad; 3330 off_t length; 3331 }; 3332 #endif 3333 int 3334 truncate(td, uap) 3335 struct thread *td; 3336 register struct truncate_args /* { 3337 char *path; 3338 int pad; 3339 off_t length; 3340 } */ *uap; 3341 { 3342 3343 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); 3344 } 3345 3346 int 3347 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) 3348 { 3349 struct mount *mp; 3350 struct vnode *vp; 3351 struct vattr vattr; 3352 int error; 3353 struct nameidata nd; 3354 int vfslocked; 3355 3356 if (length < 0) 3357 return(EINVAL); 3358 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3359 if ((error = namei(&nd)) != 0) 3360 return (error); 3361 vfslocked = NDHASGIANT(&nd); 3362 vp = nd.ni_vp; 3363 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 3364 vrele(vp); 3365 VFS_UNLOCK_GIANT(vfslocked); 3366 return (error); 3367 } 3368 NDFREE(&nd, NDF_ONLY_PNBUF); 3369 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3370 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3371 if (vp->v_type == VDIR) 3372 error = EISDIR; 3373 #ifdef MAC 3374 else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { 3375 } 3376 #endif 3377 else if ((error = vn_writechk(vp)) == 0 && 3378 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { 3379 VATTR_NULL(&vattr); 3380 vattr.va_size = length; 3381 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3382 } 3383 vput(vp); 3384 vn_finished_write(mp); 3385 VFS_UNLOCK_GIANT(vfslocked); 3386 return (error); 3387 } 3388 3389 #if defined(COMPAT_43) 3390 /* 3391 * Truncate a file given its path name. 3392 */ 3393 #ifndef _SYS_SYSPROTO_H_ 3394 struct otruncate_args { 3395 char *path; 3396 long length; 3397 }; 3398 #endif 3399 int 3400 otruncate(td, uap) 3401 struct thread *td; 3402 register struct otruncate_args /* { 3403 char *path; 3404 long length; 3405 } */ *uap; 3406 { 3407 struct truncate_args /* { 3408 char *path; 3409 int pad; 3410 off_t length; 3411 } */ nuap; 3412 3413 nuap.path = uap->path; 3414 nuap.length = uap->length; 3415 return (truncate(td, &nuap)); 3416 } 3417 #endif /* COMPAT_43 */ 3418 3419 /* Versions with the pad argument */ 3420 int 3421 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) 3422 { 3423 struct truncate_args ouap; 3424 3425 ouap.path = uap->path; 3426 ouap.length = uap->length; 3427 return (truncate(td, &ouap)); 3428 } 3429 3430 int 3431 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) 3432 { 3433 struct ftruncate_args ouap; 3434 3435 ouap.fd = uap->fd; 3436 ouap.length = uap->length; 3437 return (ftruncate(td, &ouap)); 3438 } 3439 3440 /* 3441 * Sync an open file. 3442 */ 3443 #ifndef _SYS_SYSPROTO_H_ 3444 struct fsync_args { 3445 int fd; 3446 }; 3447 #endif 3448 int 3449 fsync(td, uap) 3450 struct thread *td; 3451 struct fsync_args /* { 3452 int fd; 3453 } */ *uap; 3454 { 3455 struct vnode *vp; 3456 struct mount *mp; 3457 struct file *fp; 3458 int vfslocked; 3459 int error; 3460 3461 AUDIT_ARG(fd, uap->fd); 3462 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3463 return (error); 3464 vp = fp->f_vnode; 3465 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3466 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3467 goto drop; 3468 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3469 AUDIT_ARG(vnode, vp, ARG_VNODE1); 3470 if (vp->v_object != NULL) { 3471 VM_OBJECT_LOCK(vp->v_object); 3472 vm_object_page_clean(vp->v_object, 0, 0, 0); 3473 VM_OBJECT_UNLOCK(vp->v_object); 3474 } 3475 error = VOP_FSYNC(vp, MNT_WAIT, td); 3476 3477 VOP_UNLOCK(vp, 0); 3478 vn_finished_write(mp); 3479 drop: 3480 VFS_UNLOCK_GIANT(vfslocked); 3481 fdrop(fp, td); 3482 return (error); 3483 } 3484 3485 /* 3486 * Rename files. Source and destination must either both be directories, or 3487 * both not be directories. If target is a directory, it must be empty. 3488 */ 3489 #ifndef _SYS_SYSPROTO_H_ 3490 struct rename_args { 3491 char *from; 3492 char *to; 3493 }; 3494 #endif 3495 int 3496 rename(td, uap) 3497 struct thread *td; 3498 register struct rename_args /* { 3499 char *from; 3500 char *to; 3501 } */ *uap; 3502 { 3503 3504 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); 3505 } 3506 3507 #ifndef _SYS_SYSPROTO_H_ 3508 struct renameat_args { 3509 int oldfd; 3510 char *old; 3511 int newfd; 3512 char *new; 3513 }; 3514 #endif 3515 int 3516 renameat(struct thread *td, struct renameat_args *uap) 3517 { 3518 3519 return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, 3520 UIO_USERSPACE)); 3521 } 3522 3523 int 3524 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) 3525 { 3526 3527 return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); 3528 } 3529 3530 int 3531 kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, 3532 enum uio_seg pathseg) 3533 { 3534 struct mount *mp = NULL; 3535 struct vnode *tvp, *fvp, *tdvp; 3536 struct nameidata fromnd, tond; 3537 int tvfslocked; 3538 int fvfslocked; 3539 int error; 3540 3541 bwillwrite(); 3542 #ifdef MAC 3543 NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | 3544 AUDITVNODE1, pathseg, old, oldfd, td); 3545 #else 3546 NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | 3547 AUDITVNODE1, pathseg, old, oldfd, td); 3548 #endif 3549 3550 if ((error = namei(&fromnd)) != 0) 3551 return (error); 3552 fvfslocked = NDHASGIANT(&fromnd); 3553 tvfslocked = 0; 3554 #ifdef MAC 3555 error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp, 3556 fromnd.ni_vp, &fromnd.ni_cnd); 3557 VOP_UNLOCK(fromnd.ni_dvp, 0); 3558 if (fromnd.ni_dvp != fromnd.ni_vp) 3559 VOP_UNLOCK(fromnd.ni_vp, 0); 3560 #endif 3561 fvp = fromnd.ni_vp; 3562 if (error == 0) 3563 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); 3564 if (error != 0) { 3565 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3566 vrele(fromnd.ni_dvp); 3567 vrele(fvp); 3568 goto out1; 3569 } 3570 NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | 3571 MPSAFE | AUDITVNODE2, pathseg, new, newfd, td); 3572 if (fromnd.ni_vp->v_type == VDIR) 3573 tond.ni_cnd.cn_flags |= WILLBEDIR; 3574 if ((error = namei(&tond)) != 0) { 3575 /* Translate error code for rename("dir1", "dir2/."). */ 3576 if (error == EISDIR && fvp->v_type == VDIR) 3577 error = EINVAL; 3578 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3579 vrele(fromnd.ni_dvp); 3580 vrele(fvp); 3581 vn_finished_write(mp); 3582 goto out1; 3583 } 3584 tvfslocked = NDHASGIANT(&tond); 3585 tdvp = tond.ni_dvp; 3586 tvp = tond.ni_vp; 3587 if (tvp != NULL) { 3588 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 3589 error = ENOTDIR; 3590 goto out; 3591 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 3592 error = EISDIR; 3593 goto out; 3594 } 3595 } 3596 if (fvp == tdvp) { 3597 error = EINVAL; 3598 goto out; 3599 } 3600 /* 3601 * If the source is the same as the destination (that is, if they 3602 * are links to the same vnode), then there is nothing to do. 3603 */ 3604 if (fvp == tvp) 3605 error = -1; 3606 #ifdef MAC 3607 else 3608 error = mac_vnode_check_rename_to(td->td_ucred, tdvp, 3609 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); 3610 #endif 3611 out: 3612 if (!error) { 3613 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); 3614 if (fromnd.ni_dvp != tdvp) { 3615 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3616 } 3617 if (tvp) { 3618 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); 3619 } 3620 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 3621 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 3622 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3623 NDFREE(&tond, NDF_ONLY_PNBUF); 3624 } else { 3625 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3626 NDFREE(&tond, NDF_ONLY_PNBUF); 3627 if (tvp) 3628 vput(tvp); 3629 if (tdvp == tvp) 3630 vrele(tdvp); 3631 else 3632 vput(tdvp); 3633 vrele(fromnd.ni_dvp); 3634 vrele(fvp); 3635 } 3636 vrele(tond.ni_startdir); 3637 vn_finished_write(mp); 3638 out1: 3639 if (fromnd.ni_startdir) 3640 vrele(fromnd.ni_startdir); 3641 VFS_UNLOCK_GIANT(fvfslocked); 3642 VFS_UNLOCK_GIANT(tvfslocked); 3643 if (error == -1) 3644 return (0); 3645 return (error); 3646 } 3647 3648 /* 3649 * Make a directory file. 3650 */ 3651 #ifndef _SYS_SYSPROTO_H_ 3652 struct mkdir_args { 3653 char *path; 3654 int mode; 3655 }; 3656 #endif 3657 int 3658 mkdir(td, uap) 3659 struct thread *td; 3660 register struct mkdir_args /* { 3661 char *path; 3662 int mode; 3663 } */ *uap; 3664 { 3665 3666 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); 3667 } 3668 3669 #ifndef _SYS_SYSPROTO_H_ 3670 struct mkdirat_args { 3671 int fd; 3672 char *path; 3673 mode_t mode; 3674 }; 3675 #endif 3676 int 3677 mkdirat(struct thread *td, struct mkdirat_args *uap) 3678 { 3679 3680 return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); 3681 } 3682 3683 int 3684 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) 3685 { 3686 3687 return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); 3688 } 3689 3690 int 3691 kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, 3692 int mode) 3693 { 3694 struct mount *mp; 3695 struct vnode *vp; 3696 struct vattr vattr; 3697 int error; 3698 struct nameidata nd; 3699 int vfslocked; 3700 3701 AUDIT_ARG(mode, mode); 3702 restart: 3703 bwillwrite(); 3704 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 3705 segflg, path, fd, td); 3706 nd.ni_cnd.cn_flags |= WILLBEDIR; 3707 if ((error = namei(&nd)) != 0) 3708 return (error); 3709 vfslocked = NDHASGIANT(&nd); 3710 vp = nd.ni_vp; 3711 if (vp != NULL) { 3712 NDFREE(&nd, NDF_ONLY_PNBUF); 3713 /* 3714 * XXX namei called with LOCKPARENT but not LOCKLEAF has 3715 * the strange behaviour of leaving the vnode unlocked 3716 * if the target is the same vnode as the parent. 3717 */ 3718 if (vp == nd.ni_dvp) 3719 vrele(nd.ni_dvp); 3720 else 3721 vput(nd.ni_dvp); 3722 vrele(vp); 3723 VFS_UNLOCK_GIANT(vfslocked); 3724 return (EEXIST); 3725 } 3726 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3727 NDFREE(&nd, NDF_ONLY_PNBUF); 3728 vput(nd.ni_dvp); 3729 VFS_UNLOCK_GIANT(vfslocked); 3730 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3731 return (error); 3732 goto restart; 3733 } 3734 VATTR_NULL(&vattr); 3735 vattr.va_type = VDIR; 3736 FILEDESC_SLOCK(td->td_proc->p_fd); 3737 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; 3738 FILEDESC_SUNLOCK(td->td_proc->p_fd); 3739 #ifdef MAC 3740 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 3741 &vattr); 3742 if (error) 3743 goto out; 3744 #endif 3745 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3746 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 3747 #ifdef MAC 3748 out: 3749 #endif 3750 NDFREE(&nd, NDF_ONLY_PNBUF); 3751 vput(nd.ni_dvp); 3752 if (!error) 3753 vput(nd.ni_vp); 3754 vn_finished_write(mp); 3755 VFS_UNLOCK_GIANT(vfslocked); 3756 return (error); 3757 } 3758 3759 /* 3760 * Remove a directory file. 3761 */ 3762 #ifndef _SYS_SYSPROTO_H_ 3763 struct rmdir_args { 3764 char *path; 3765 }; 3766 #endif 3767 int 3768 rmdir(td, uap) 3769 struct thread *td; 3770 struct rmdir_args /* { 3771 char *path; 3772 } */ *uap; 3773 { 3774 3775 return (kern_rmdir(td, uap->path, UIO_USERSPACE)); 3776 } 3777 3778 int 3779 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) 3780 { 3781 3782 return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); 3783 } 3784 3785 int 3786 kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 3787 { 3788 struct mount *mp; 3789 struct vnode *vp; 3790 int error; 3791 struct nameidata nd; 3792 int vfslocked; 3793 3794 restart: 3795 bwillwrite(); 3796 NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, 3797 pathseg, path, fd, td); 3798 if ((error = namei(&nd)) != 0) 3799 return (error); 3800 vfslocked = NDHASGIANT(&nd); 3801 vp = nd.ni_vp; 3802 if (vp->v_type != VDIR) { 3803 error = ENOTDIR; 3804 goto out; 3805 } 3806 /* 3807 * No rmdir "." please. 3808 */ 3809 if (nd.ni_dvp == vp) { 3810 error = EINVAL; 3811 goto out; 3812 } 3813 /* 3814 * The root of a mounted filesystem cannot be deleted. 3815 */ 3816 if (vp->v_vflag & VV_ROOT) { 3817 error = EBUSY; 3818 goto out; 3819 } 3820 #ifdef MAC 3821 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 3822 &nd.ni_cnd); 3823 if (error) 3824 goto out; 3825 #endif 3826 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3827 NDFREE(&nd, NDF_ONLY_PNBUF); 3828 vput(vp); 3829 if (nd.ni_dvp == vp) 3830 vrele(nd.ni_dvp); 3831 else 3832 vput(nd.ni_dvp); 3833 VFS_UNLOCK_GIANT(vfslocked); 3834 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3835 return (error); 3836 goto restart; 3837 } 3838 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3839 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3840 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 3841 vn_finished_write(mp); 3842 out: 3843 NDFREE(&nd, NDF_ONLY_PNBUF); 3844 vput(vp); 3845 if (nd.ni_dvp == vp) 3846 vrele(nd.ni_dvp); 3847 else 3848 vput(nd.ni_dvp); 3849 VFS_UNLOCK_GIANT(vfslocked); 3850 return (error); 3851 } 3852 3853 #ifdef COMPAT_43 3854 /* 3855 * Read a block of directory entries in a filesystem independent format. 3856 */ 3857 #ifndef _SYS_SYSPROTO_H_ 3858 struct ogetdirentries_args { 3859 int fd; 3860 char *buf; 3861 u_int count; 3862 long *basep; 3863 }; 3864 #endif 3865 int 3866 ogetdirentries(td, uap) 3867 struct thread *td; 3868 register struct ogetdirentries_args /* { 3869 int fd; 3870 char *buf; 3871 u_int count; 3872 long *basep; 3873 } */ *uap; 3874 { 3875 struct vnode *vp; 3876 struct file *fp; 3877 struct uio auio, kuio; 3878 struct iovec aiov, kiov; 3879 struct dirent *dp, *edp; 3880 caddr_t dirbuf; 3881 int error, eofflag, readcnt, vfslocked; 3882 long loff; 3883 3884 /* XXX arbitrary sanity limit on `count'. */ 3885 if (uap->count > 64 * 1024) 3886 return (EINVAL); 3887 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3888 return (error); 3889 if ((fp->f_flag & FREAD) == 0) { 3890 fdrop(fp, td); 3891 return (EBADF); 3892 } 3893 vp = fp->f_vnode; 3894 unionread: 3895 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3896 if (vp->v_type != VDIR) { 3897 VFS_UNLOCK_GIANT(vfslocked); 3898 fdrop(fp, td); 3899 return (EINVAL); 3900 } 3901 aiov.iov_base = uap->buf; 3902 aiov.iov_len = uap->count; 3903 auio.uio_iov = &aiov; 3904 auio.uio_iovcnt = 1; 3905 auio.uio_rw = UIO_READ; 3906 auio.uio_segflg = UIO_USERSPACE; 3907 auio.uio_td = td; 3908 auio.uio_resid = uap->count; 3909 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3910 loff = auio.uio_offset = fp->f_offset; 3911 #ifdef MAC 3912 error = mac_vnode_check_readdir(td->td_ucred, vp); 3913 if (error) { 3914 VOP_UNLOCK(vp, 0); 3915 VFS_UNLOCK_GIANT(vfslocked); 3916 fdrop(fp, td); 3917 return (error); 3918 } 3919 #endif 3920 # if (BYTE_ORDER != LITTLE_ENDIAN) 3921 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 3922 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 3923 NULL, NULL); 3924 fp->f_offset = auio.uio_offset; 3925 } else 3926 # endif 3927 { 3928 kuio = auio; 3929 kuio.uio_iov = &kiov; 3930 kuio.uio_segflg = UIO_SYSSPACE; 3931 kiov.iov_len = uap->count; 3932 dirbuf = malloc(uap->count, M_TEMP, M_WAITOK); 3933 kiov.iov_base = dirbuf; 3934 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 3935 NULL, NULL); 3936 fp->f_offset = kuio.uio_offset; 3937 if (error == 0) { 3938 readcnt = uap->count - kuio.uio_resid; 3939 edp = (struct dirent *)&dirbuf[readcnt]; 3940 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 3941 # if (BYTE_ORDER == LITTLE_ENDIAN) 3942 /* 3943 * The expected low byte of 3944 * dp->d_namlen is our dp->d_type. 3945 * The high MBZ byte of dp->d_namlen 3946 * is our dp->d_namlen. 3947 */ 3948 dp->d_type = dp->d_namlen; 3949 dp->d_namlen = 0; 3950 # else 3951 /* 3952 * The dp->d_type is the high byte 3953 * of the expected dp->d_namlen, 3954 * so must be zero'ed. 3955 */ 3956 dp->d_type = 0; 3957 # endif 3958 if (dp->d_reclen > 0) { 3959 dp = (struct dirent *) 3960 ((char *)dp + dp->d_reclen); 3961 } else { 3962 error = EIO; 3963 break; 3964 } 3965 } 3966 if (dp >= edp) 3967 error = uiomove(dirbuf, readcnt, &auio); 3968 } 3969 free(dirbuf, M_TEMP); 3970 } 3971 if (error) { 3972 VOP_UNLOCK(vp, 0); 3973 VFS_UNLOCK_GIANT(vfslocked); 3974 fdrop(fp, td); 3975 return (error); 3976 } 3977 if (uap->count == auio.uio_resid && 3978 (vp->v_vflag & VV_ROOT) && 3979 (vp->v_mount->mnt_flag & MNT_UNION)) { 3980 struct vnode *tvp = vp; 3981 vp = vp->v_mount->mnt_vnodecovered; 3982 VREF(vp); 3983 fp->f_vnode = vp; 3984 fp->f_data = vp; 3985 fp->f_offset = 0; 3986 vput(tvp); 3987 VFS_UNLOCK_GIANT(vfslocked); 3988 goto unionread; 3989 } 3990 VOP_UNLOCK(vp, 0); 3991 VFS_UNLOCK_GIANT(vfslocked); 3992 error = copyout(&loff, uap->basep, sizeof(long)); 3993 fdrop(fp, td); 3994 td->td_retval[0] = uap->count - auio.uio_resid; 3995 return (error); 3996 } 3997 #endif /* COMPAT_43 */ 3998 3999 /* 4000 * Read a block of directory entries in a filesystem independent format. 4001 */ 4002 #ifndef _SYS_SYSPROTO_H_ 4003 struct getdirentries_args { 4004 int fd; 4005 char *buf; 4006 u_int count; 4007 long *basep; 4008 }; 4009 #endif 4010 int 4011 getdirentries(td, uap) 4012 struct thread *td; 4013 register struct getdirentries_args /* { 4014 int fd; 4015 char *buf; 4016 u_int count; 4017 long *basep; 4018 } */ *uap; 4019 { 4020 long base; 4021 int error; 4022 4023 error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); 4024 if (error) 4025 return (error); 4026 if (uap->basep != NULL) 4027 error = copyout(&base, uap->basep, sizeof(long)); 4028 return (error); 4029 } 4030 4031 int 4032 kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, 4033 long *basep) 4034 { 4035 struct vnode *vp; 4036 struct file *fp; 4037 struct uio auio; 4038 struct iovec aiov; 4039 int vfslocked; 4040 long loff; 4041 int error, eofflag; 4042 4043 AUDIT_ARG(fd, fd); 4044 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 4045 return (error); 4046 if ((fp->f_flag & FREAD) == 0) { 4047 fdrop(fp, td); 4048 return (EBADF); 4049 } 4050 vp = fp->f_vnode; 4051 unionread: 4052 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 4053 if (vp->v_type != VDIR) { 4054 VFS_UNLOCK_GIANT(vfslocked); 4055 error = EINVAL; 4056 goto fail; 4057 } 4058 aiov.iov_base = buf; 4059 aiov.iov_len = count; 4060 auio.uio_iov = &aiov; 4061 auio.uio_iovcnt = 1; 4062 auio.uio_rw = UIO_READ; 4063 auio.uio_segflg = UIO_USERSPACE; 4064 auio.uio_td = td; 4065 auio.uio_resid = count; 4066 /* vn_lock(vp, LK_SHARED | LK_RETRY); */ 4067 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4068 AUDIT_ARG(vnode, vp, ARG_VNODE1); 4069 loff = auio.uio_offset = fp->f_offset; 4070 #ifdef MAC 4071 error = mac_vnode_check_readdir(td->td_ucred, vp); 4072 if (error == 0) 4073 #endif 4074 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, 4075 NULL); 4076 fp->f_offset = auio.uio_offset; 4077 if (error) { 4078 VOP_UNLOCK(vp, 0); 4079 VFS_UNLOCK_GIANT(vfslocked); 4080 goto fail; 4081 } 4082 if (count == auio.uio_resid && 4083 (vp->v_vflag & VV_ROOT) && 4084 (vp->v_mount->mnt_flag & MNT_UNION)) { 4085 struct vnode *tvp = vp; 4086 vp = vp->v_mount->mnt_vnodecovered; 4087 VREF(vp); 4088 fp->f_vnode = vp; 4089 fp->f_data = vp; 4090 fp->f_offset = 0; 4091 vput(tvp); 4092 VFS_UNLOCK_GIANT(vfslocked); 4093 goto unionread; 4094 } 4095 VOP_UNLOCK(vp, 0); 4096 VFS_UNLOCK_GIANT(vfslocked); 4097 *basep = loff; 4098 td->td_retval[0] = count - auio.uio_resid; 4099 fail: 4100 fdrop(fp, td); 4101 return (error); 4102 } 4103 4104 #ifndef _SYS_SYSPROTO_H_ 4105 struct getdents_args { 4106 int fd; 4107 char *buf; 4108 size_t count; 4109 }; 4110 #endif 4111 int 4112 getdents(td, uap) 4113 struct thread *td; 4114 register struct getdents_args /* { 4115 int fd; 4116 char *buf; 4117 u_int count; 4118 } */ *uap; 4119 { 4120 struct getdirentries_args ap; 4121 ap.fd = uap->fd; 4122 ap.buf = uap->buf; 4123 ap.count = uap->count; 4124 ap.basep = NULL; 4125 return (getdirentries(td, &ap)); 4126 } 4127 4128 /* 4129 * Set the mode mask for creation of filesystem nodes. 4130 */ 4131 #ifndef _SYS_SYSPROTO_H_ 4132 struct umask_args { 4133 int newmask; 4134 }; 4135 #endif 4136 int 4137 umask(td, uap) 4138 struct thread *td; 4139 struct umask_args /* { 4140 int newmask; 4141 } */ *uap; 4142 { 4143 register struct filedesc *fdp; 4144 4145 FILEDESC_XLOCK(td->td_proc->p_fd); 4146 fdp = td->td_proc->p_fd; 4147 td->td_retval[0] = fdp->fd_cmask; 4148 fdp->fd_cmask = uap->newmask & ALLPERMS; 4149 FILEDESC_XUNLOCK(td->td_proc->p_fd); 4150 return (0); 4151 } 4152 4153 /* 4154 * Void all references to file by ripping underlying filesystem away from 4155 * vnode. 4156 */ 4157 #ifndef _SYS_SYSPROTO_H_ 4158 struct revoke_args { 4159 char *path; 4160 }; 4161 #endif 4162 int 4163 revoke(td, uap) 4164 struct thread *td; 4165 register struct revoke_args /* { 4166 char *path; 4167 } */ *uap; 4168 { 4169 struct vnode *vp; 4170 struct vattr vattr; 4171 int error; 4172 struct nameidata nd; 4173 int vfslocked; 4174 4175 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4176 UIO_USERSPACE, uap->path, td); 4177 if ((error = namei(&nd)) != 0) 4178 return (error); 4179 vfslocked = NDHASGIANT(&nd); 4180 vp = nd.ni_vp; 4181 NDFREE(&nd, NDF_ONLY_PNBUF); 4182 if (vp->v_type != VCHR) { 4183 error = EINVAL; 4184 goto out; 4185 } 4186 #ifdef MAC 4187 error = mac_vnode_check_revoke(td->td_ucred, vp); 4188 if (error) 4189 goto out; 4190 #endif 4191 error = VOP_GETATTR(vp, &vattr, td->td_ucred); 4192 if (error) 4193 goto out; 4194 if (td->td_ucred->cr_uid != vattr.va_uid) { 4195 error = priv_check(td, PRIV_VFS_ADMIN); 4196 if (error) 4197 goto out; 4198 } 4199 if (vcount(vp) > 1) 4200 VOP_REVOKE(vp, REVOKEALL); 4201 out: 4202 vput(vp); 4203 VFS_UNLOCK_GIANT(vfslocked); 4204 return (error); 4205 } 4206 4207 /* 4208 * Convert a user file descriptor to a kernel file entry. 4209 * A reference on the file entry is held upon returning. 4210 */ 4211 int 4212 getvnode(fdp, fd, fpp) 4213 struct filedesc *fdp; 4214 int fd; 4215 struct file **fpp; 4216 { 4217 int error; 4218 struct file *fp; 4219 4220 fp = NULL; 4221 if (fdp == NULL) 4222 error = EBADF; 4223 else { 4224 FILEDESC_SLOCK(fdp); 4225 if ((u_int)fd >= fdp->fd_nfiles || 4226 (fp = fdp->fd_ofiles[fd]) == NULL) 4227 error = EBADF; 4228 else if (fp->f_vnode == NULL) { 4229 fp = NULL; 4230 error = EINVAL; 4231 } else { 4232 fhold(fp); 4233 error = 0; 4234 } 4235 FILEDESC_SUNLOCK(fdp); 4236 } 4237 *fpp = fp; 4238 return (error); 4239 } 4240 4241 /* 4242 * Get an (NFS) file handle. 4243 */ 4244 #ifndef _SYS_SYSPROTO_H_ 4245 struct lgetfh_args { 4246 char *fname; 4247 fhandle_t *fhp; 4248 }; 4249 #endif 4250 int 4251 lgetfh(td, uap) 4252 struct thread *td; 4253 register struct lgetfh_args *uap; 4254 { 4255 struct nameidata nd; 4256 fhandle_t fh; 4257 register struct vnode *vp; 4258 int vfslocked; 4259 int error; 4260 4261 error = priv_check(td, PRIV_VFS_GETFH); 4262 if (error) 4263 return (error); 4264 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4265 UIO_USERSPACE, uap->fname, td); 4266 error = namei(&nd); 4267 if (error) 4268 return (error); 4269 vfslocked = NDHASGIANT(&nd); 4270 NDFREE(&nd, NDF_ONLY_PNBUF); 4271 vp = nd.ni_vp; 4272 bzero(&fh, sizeof(fh)); 4273 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4274 error = VOP_VPTOFH(vp, &fh.fh_fid); 4275 vput(vp); 4276 VFS_UNLOCK_GIANT(vfslocked); 4277 if (error) 4278 return (error); 4279 error = copyout(&fh, uap->fhp, sizeof (fh)); 4280 return (error); 4281 } 4282 4283 #ifndef _SYS_SYSPROTO_H_ 4284 struct getfh_args { 4285 char *fname; 4286 fhandle_t *fhp; 4287 }; 4288 #endif 4289 int 4290 getfh(td, uap) 4291 struct thread *td; 4292 register struct getfh_args *uap; 4293 { 4294 struct nameidata nd; 4295 fhandle_t fh; 4296 register struct vnode *vp; 4297 int vfslocked; 4298 int error; 4299 4300 error = priv_check(td, PRIV_VFS_GETFH); 4301 if (error) 4302 return (error); 4303 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4304 UIO_USERSPACE, uap->fname, td); 4305 error = namei(&nd); 4306 if (error) 4307 return (error); 4308 vfslocked = NDHASGIANT(&nd); 4309 NDFREE(&nd, NDF_ONLY_PNBUF); 4310 vp = nd.ni_vp; 4311 bzero(&fh, sizeof(fh)); 4312 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4313 error = VOP_VPTOFH(vp, &fh.fh_fid); 4314 vput(vp); 4315 VFS_UNLOCK_GIANT(vfslocked); 4316 if (error) 4317 return (error); 4318 error = copyout(&fh, uap->fhp, sizeof (fh)); 4319 return (error); 4320 } 4321 4322 /* 4323 * syscall for the rpc.lockd to use to translate a NFS file handle into an 4324 * open descriptor. 4325 * 4326 * warning: do not remove the priv_check() call or this becomes one giant 4327 * security hole. 4328 */ 4329 #ifndef _SYS_SYSPROTO_H_ 4330 struct fhopen_args { 4331 const struct fhandle *u_fhp; 4332 int flags; 4333 }; 4334 #endif 4335 int 4336 fhopen(td, uap) 4337 struct thread *td; 4338 struct fhopen_args /* { 4339 const struct fhandle *u_fhp; 4340 int flags; 4341 } */ *uap; 4342 { 4343 struct proc *p = td->td_proc; 4344 struct mount *mp; 4345 struct vnode *vp; 4346 struct fhandle fhp; 4347 struct vattr vat; 4348 struct vattr *vap = &vat; 4349 struct flock lf; 4350 struct file *fp; 4351 register struct filedesc *fdp = p->p_fd; 4352 int fmode, mode, error, type; 4353 struct file *nfp; 4354 int vfslocked; 4355 int indx; 4356 4357 error = priv_check(td, PRIV_VFS_FHOPEN); 4358 if (error) 4359 return (error); 4360 fmode = FFLAGS(uap->flags); 4361 /* why not allow a non-read/write open for our lockd? */ 4362 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 4363 return (EINVAL); 4364 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 4365 if (error) 4366 return(error); 4367 /* find the mount point */ 4368 mp = vfs_getvfs(&fhp.fh_fsid); 4369 if (mp == NULL) 4370 return (ESTALE); 4371 vfslocked = VFS_LOCK_GIANT(mp); 4372 /* now give me my vnode, it gets returned to me locked */ 4373 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 4374 if (error) 4375 goto out; 4376 /* 4377 * from now on we have to make sure not 4378 * to forget about the vnode 4379 * any error that causes an abort must vput(vp) 4380 * just set error = err and 'goto bad;'. 4381 */ 4382 4383 /* 4384 * from vn_open 4385 */ 4386 if (vp->v_type == VLNK) { 4387 error = EMLINK; 4388 goto bad; 4389 } 4390 if (vp->v_type == VSOCK) { 4391 error = EOPNOTSUPP; 4392 goto bad; 4393 } 4394 mode = 0; 4395 if (fmode & (FWRITE | O_TRUNC)) { 4396 if (vp->v_type == VDIR) { 4397 error = EISDIR; 4398 goto bad; 4399 } 4400 error = vn_writechk(vp); 4401 if (error) 4402 goto bad; 4403 mode |= VWRITE; 4404 } 4405 if (fmode & FREAD) 4406 mode |= VREAD; 4407 if (fmode & O_APPEND) 4408 mode |= VAPPEND; 4409 #ifdef MAC 4410 error = mac_vnode_check_open(td->td_ucred, vp, mode); 4411 if (error) 4412 goto bad; 4413 #endif 4414 if (mode) { 4415 error = VOP_ACCESS(vp, mode, td->td_ucred, td); 4416 if (error) 4417 goto bad; 4418 } 4419 if (fmode & O_TRUNC) { 4420 VOP_UNLOCK(vp, 0); /* XXX */ 4421 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) { 4422 vrele(vp); 4423 goto out; 4424 } 4425 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 4426 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ 4427 #ifdef MAC 4428 /* 4429 * We don't yet have fp->f_cred, so use td->td_ucred, which 4430 * should be right. 4431 */ 4432 error = mac_vnode_check_write(td->td_ucred, td->td_ucred, vp); 4433 if (error == 0) { 4434 #endif 4435 VATTR_NULL(vap); 4436 vap->va_size = 0; 4437 error = VOP_SETATTR(vp, vap, td->td_ucred); 4438 #ifdef MAC 4439 } 4440 #endif 4441 vn_finished_write(mp); 4442 if (error) 4443 goto bad; 4444 } 4445 error = VOP_OPEN(vp, fmode, td->td_ucred, td, NULL); 4446 if (error) 4447 goto bad; 4448 4449 if (fmode & FWRITE) 4450 vp->v_writecount++; 4451 4452 /* 4453 * end of vn_open code 4454 */ 4455 4456 if ((error = falloc(td, &nfp, &indx)) != 0) { 4457 if (fmode & FWRITE) 4458 vp->v_writecount--; 4459 goto bad; 4460 } 4461 /* An extra reference on `nfp' has been held for us by falloc(). */ 4462 fp = nfp; 4463 nfp->f_vnode = vp; 4464 finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops); 4465 if (fmode & (O_EXLOCK | O_SHLOCK)) { 4466 lf.l_whence = SEEK_SET; 4467 lf.l_start = 0; 4468 lf.l_len = 0; 4469 if (fmode & O_EXLOCK) 4470 lf.l_type = F_WRLCK; 4471 else 4472 lf.l_type = F_RDLCK; 4473 type = F_FLOCK; 4474 if ((fmode & FNONBLOCK) == 0) 4475 type |= F_WAIT; 4476 VOP_UNLOCK(vp, 0); 4477 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 4478 type)) != 0) { 4479 /* 4480 * The lock request failed. Normally close the 4481 * descriptor but handle the case where someone might 4482 * have dup()d or close()d it when we weren't looking. 4483 */ 4484 fdclose(fdp, fp, indx, td); 4485 4486 /* 4487 * release our private reference 4488 */ 4489 fdrop(fp, td); 4490 goto out; 4491 } 4492 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4493 atomic_set_int(&fp->f_flag, FHASLOCK); 4494 } 4495 4496 VOP_UNLOCK(vp, 0); 4497 fdrop(fp, td); 4498 vfs_rel(mp); 4499 VFS_UNLOCK_GIANT(vfslocked); 4500 td->td_retval[0] = indx; 4501 return (0); 4502 4503 bad: 4504 vput(vp); 4505 out: 4506 vfs_rel(mp); 4507 VFS_UNLOCK_GIANT(vfslocked); 4508 return (error); 4509 } 4510 4511 /* 4512 * Stat an (NFS) file handle. 4513 */ 4514 #ifndef _SYS_SYSPROTO_H_ 4515 struct fhstat_args { 4516 struct fhandle *u_fhp; 4517 struct stat *sb; 4518 }; 4519 #endif 4520 int 4521 fhstat(td, uap) 4522 struct thread *td; 4523 register struct fhstat_args /* { 4524 struct fhandle *u_fhp; 4525 struct stat *sb; 4526 } */ *uap; 4527 { 4528 struct stat sb; 4529 fhandle_t fh; 4530 struct mount *mp; 4531 struct vnode *vp; 4532 int vfslocked; 4533 int error; 4534 4535 error = priv_check(td, PRIV_VFS_FHSTAT); 4536 if (error) 4537 return (error); 4538 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4539 if (error) 4540 return (error); 4541 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 4542 return (ESTALE); 4543 vfslocked = VFS_LOCK_GIANT(mp); 4544 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) { 4545 vfs_rel(mp); 4546 VFS_UNLOCK_GIANT(vfslocked); 4547 return (error); 4548 } 4549 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 4550 vput(vp); 4551 vfs_rel(mp); 4552 VFS_UNLOCK_GIANT(vfslocked); 4553 if (error) 4554 return (error); 4555 error = copyout(&sb, uap->sb, sizeof(sb)); 4556 return (error); 4557 } 4558 4559 /* 4560 * Implement fstatfs() for (NFS) file handles. 4561 */ 4562 #ifndef _SYS_SYSPROTO_H_ 4563 struct fhstatfs_args { 4564 struct fhandle *u_fhp; 4565 struct statfs *buf; 4566 }; 4567 #endif 4568 int 4569 fhstatfs(td, uap) 4570 struct thread *td; 4571 struct fhstatfs_args /* { 4572 struct fhandle *u_fhp; 4573 struct statfs *buf; 4574 } */ *uap; 4575 { 4576 struct statfs sf; 4577 fhandle_t fh; 4578 int error; 4579 4580 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4581 if (error) 4582 return (error); 4583 error = kern_fhstatfs(td, fh, &sf); 4584 if (error) 4585 return (error); 4586 return (copyout(&sf, uap->buf, sizeof(sf))); 4587 } 4588 4589 int 4590 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) 4591 { 4592 struct statfs *sp; 4593 struct mount *mp; 4594 struct vnode *vp; 4595 int vfslocked; 4596 int error; 4597 4598 error = priv_check(td, PRIV_VFS_FHSTATFS); 4599 if (error) 4600 return (error); 4601 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 4602 return (ESTALE); 4603 vfslocked = VFS_LOCK_GIANT(mp); 4604 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); 4605 if (error) { 4606 VFS_UNLOCK_GIANT(vfslocked); 4607 vfs_rel(mp); 4608 return (error); 4609 } 4610 vput(vp); 4611 error = prison_canseemount(td->td_ucred, mp); 4612 if (error) 4613 goto out; 4614 #ifdef MAC 4615 error = mac_mount_check_stat(td->td_ucred, mp); 4616 if (error) 4617 goto out; 4618 #endif 4619 /* 4620 * Set these in case the underlying filesystem fails to do so. 4621 */ 4622 sp = &mp->mnt_stat; 4623 sp->f_version = STATFS_VERSION; 4624 sp->f_namemax = NAME_MAX; 4625 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 4626 error = VFS_STATFS(mp, sp, td); 4627 if (error == 0) 4628 *buf = *sp; 4629 out: 4630 vfs_rel(mp); 4631 VFS_UNLOCK_GIANT(vfslocked); 4632 return (error); 4633 } 4634