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 faccessat(struct thread *td, struct faccessat_args *uap) 2088 { 2089 2090 if (uap->flag & ~AT_EACCESS) 2091 return (EINVAL); 2092 return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, 2093 uap->mode)); 2094 } 2095 2096 int 2097 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2098 { 2099 2100 return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, mode)); 2101 } 2102 2103 int 2104 kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2105 int flags, int mode) 2106 { 2107 struct ucred *cred, *tmpcred; 2108 struct vnode *vp; 2109 struct nameidata nd; 2110 int vfslocked; 2111 int error; 2112 2113 /* 2114 * Create and modify a temporary credential instead of one that 2115 * is potentially shared. This could also mess up socket 2116 * buffer accounting which can run in an interrupt context. 2117 */ 2118 if (!(flags & AT_EACCESS)) { 2119 cred = td->td_ucred; 2120 tmpcred = crdup(cred); 2121 tmpcred->cr_uid = cred->cr_ruid; 2122 tmpcred->cr_groups[0] = cred->cr_rgid; 2123 td->td_ucred = tmpcred; 2124 } else 2125 cred = tmpcred = td->td_ucred; 2126 NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2127 pathseg, path, fd, td); 2128 if ((error = namei(&nd)) != 0) 2129 goto out1; 2130 vfslocked = NDHASGIANT(&nd); 2131 vp = nd.ni_vp; 2132 2133 error = vn_access(vp, mode, tmpcred, td); 2134 NDFREE(&nd, NDF_ONLY_PNBUF); 2135 vput(vp); 2136 VFS_UNLOCK_GIANT(vfslocked); 2137 out1: 2138 if (!(flags & AT_EACCESS)) { 2139 td->td_ucred = cred; 2140 crfree(tmpcred); 2141 } 2142 return (error); 2143 } 2144 2145 /* 2146 * Check access permissions using "effective" credentials. 2147 */ 2148 #ifndef _SYS_SYSPROTO_H_ 2149 struct eaccess_args { 2150 char *path; 2151 int flags; 2152 }; 2153 #endif 2154 int 2155 eaccess(td, uap) 2156 struct thread *td; 2157 register struct eaccess_args /* { 2158 char *path; 2159 int flags; 2160 } */ *uap; 2161 { 2162 2163 return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags)); 2164 } 2165 2166 int 2167 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags) 2168 { 2169 2170 return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, flags)); 2171 } 2172 2173 #if defined(COMPAT_43) 2174 /* 2175 * Get file status; this version follows links. 2176 */ 2177 #ifndef _SYS_SYSPROTO_H_ 2178 struct ostat_args { 2179 char *path; 2180 struct ostat *ub; 2181 }; 2182 #endif 2183 int 2184 ostat(td, uap) 2185 struct thread *td; 2186 register struct ostat_args /* { 2187 char *path; 2188 struct ostat *ub; 2189 } */ *uap; 2190 { 2191 struct stat sb; 2192 struct ostat osb; 2193 int error; 2194 2195 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2196 if (error) 2197 return (error); 2198 cvtstat(&sb, &osb); 2199 error = copyout(&osb, uap->ub, sizeof (osb)); 2200 return (error); 2201 } 2202 2203 /* 2204 * Get file status; this version does not follow links. 2205 */ 2206 #ifndef _SYS_SYSPROTO_H_ 2207 struct olstat_args { 2208 char *path; 2209 struct ostat *ub; 2210 }; 2211 #endif 2212 int 2213 olstat(td, uap) 2214 struct thread *td; 2215 register struct olstat_args /* { 2216 char *path; 2217 struct ostat *ub; 2218 } */ *uap; 2219 { 2220 struct stat sb; 2221 struct ostat osb; 2222 int error; 2223 2224 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2225 if (error) 2226 return (error); 2227 cvtstat(&sb, &osb); 2228 error = copyout(&osb, uap->ub, sizeof (osb)); 2229 return (error); 2230 } 2231 2232 /* 2233 * Convert from an old to a new stat structure. 2234 */ 2235 void 2236 cvtstat(st, ost) 2237 struct stat *st; 2238 struct ostat *ost; 2239 { 2240 2241 ost->st_dev = st->st_dev; 2242 ost->st_ino = st->st_ino; 2243 ost->st_mode = st->st_mode; 2244 ost->st_nlink = st->st_nlink; 2245 ost->st_uid = st->st_uid; 2246 ost->st_gid = st->st_gid; 2247 ost->st_rdev = st->st_rdev; 2248 if (st->st_size < (quad_t)1 << 32) 2249 ost->st_size = st->st_size; 2250 else 2251 ost->st_size = -2; 2252 ost->st_atime = st->st_atime; 2253 ost->st_mtime = st->st_mtime; 2254 ost->st_ctime = st->st_ctime; 2255 ost->st_blksize = st->st_blksize; 2256 ost->st_blocks = st->st_blocks; 2257 ost->st_flags = st->st_flags; 2258 ost->st_gen = st->st_gen; 2259 } 2260 #endif /* COMPAT_43 */ 2261 2262 /* 2263 * Get file status; this version follows links. 2264 */ 2265 #ifndef _SYS_SYSPROTO_H_ 2266 struct stat_args { 2267 char *path; 2268 struct stat *ub; 2269 }; 2270 #endif 2271 int 2272 stat(td, uap) 2273 struct thread *td; 2274 register struct stat_args /* { 2275 char *path; 2276 struct stat *ub; 2277 } */ *uap; 2278 { 2279 struct stat sb; 2280 int error; 2281 2282 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2283 if (error == 0) 2284 error = copyout(&sb, uap->ub, sizeof (sb)); 2285 return (error); 2286 } 2287 2288 #ifndef _SYS_SYSPROTO_H_ 2289 struct fstatat_args { 2290 int fd; 2291 char *path; 2292 struct stat *buf; 2293 int flag; 2294 } 2295 #endif 2296 int 2297 fstatat(struct thread *td, struct fstatat_args *uap) 2298 { 2299 struct stat sb; 2300 int error; 2301 2302 error = kern_statat(td, uap->flag, uap->fd, uap->path, 2303 UIO_USERSPACE, &sb); 2304 if (error == 0) 2305 error = copyout(&sb, uap->buf, sizeof (sb)); 2306 return (error); 2307 } 2308 2309 int 2310 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2311 { 2312 2313 return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); 2314 } 2315 2316 int 2317 kern_statat(struct thread *td, int flag, int fd, char *path, 2318 enum uio_seg pathseg, struct stat *sbp) 2319 { 2320 struct nameidata nd; 2321 struct stat sb; 2322 int error, vfslocked; 2323 2324 if (flag & ~AT_SYMLINK_NOFOLLOW) 2325 return (EINVAL); 2326 2327 NDINIT_AT(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : 2328 FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, 2329 path, fd, td); 2330 2331 if ((error = namei(&nd)) != 0) 2332 return (error); 2333 vfslocked = NDHASGIANT(&nd); 2334 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 2335 NDFREE(&nd, NDF_ONLY_PNBUF); 2336 vput(nd.ni_vp); 2337 VFS_UNLOCK_GIANT(vfslocked); 2338 if (mtx_owned(&Giant)) 2339 printf("stat(%d): %s\n", vfslocked, path); 2340 if (error) 2341 return (error); 2342 *sbp = sb; 2343 #ifdef KTRACE 2344 if (KTRPOINT(td, KTR_STRUCT)) 2345 ktrstat(&sb); 2346 #endif 2347 return (0); 2348 } 2349 2350 /* 2351 * Get file status; this version does not follow links. 2352 */ 2353 #ifndef _SYS_SYSPROTO_H_ 2354 struct lstat_args { 2355 char *path; 2356 struct stat *ub; 2357 }; 2358 #endif 2359 int 2360 lstat(td, uap) 2361 struct thread *td; 2362 register struct lstat_args /* { 2363 char *path; 2364 struct stat *ub; 2365 } */ *uap; 2366 { 2367 struct stat sb; 2368 int error; 2369 2370 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2371 if (error == 0) 2372 error = copyout(&sb, uap->ub, sizeof (sb)); 2373 return (error); 2374 } 2375 2376 int 2377 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2378 { 2379 2380 return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, 2381 sbp)); 2382 } 2383 2384 /* 2385 * Implementation of the NetBSD [l]stat() functions. 2386 */ 2387 void 2388 cvtnstat(sb, nsb) 2389 struct stat *sb; 2390 struct nstat *nsb; 2391 { 2392 bzero(nsb, sizeof *nsb); 2393 nsb->st_dev = sb->st_dev; 2394 nsb->st_ino = sb->st_ino; 2395 nsb->st_mode = sb->st_mode; 2396 nsb->st_nlink = sb->st_nlink; 2397 nsb->st_uid = sb->st_uid; 2398 nsb->st_gid = sb->st_gid; 2399 nsb->st_rdev = sb->st_rdev; 2400 nsb->st_atimespec = sb->st_atimespec; 2401 nsb->st_mtimespec = sb->st_mtimespec; 2402 nsb->st_ctimespec = sb->st_ctimespec; 2403 nsb->st_size = sb->st_size; 2404 nsb->st_blocks = sb->st_blocks; 2405 nsb->st_blksize = sb->st_blksize; 2406 nsb->st_flags = sb->st_flags; 2407 nsb->st_gen = sb->st_gen; 2408 nsb->st_birthtimespec = sb->st_birthtimespec; 2409 } 2410 2411 #ifndef _SYS_SYSPROTO_H_ 2412 struct nstat_args { 2413 char *path; 2414 struct nstat *ub; 2415 }; 2416 #endif 2417 int 2418 nstat(td, uap) 2419 struct thread *td; 2420 register struct nstat_args /* { 2421 char *path; 2422 struct nstat *ub; 2423 } */ *uap; 2424 { 2425 struct stat sb; 2426 struct nstat nsb; 2427 int error; 2428 2429 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2430 if (error) 2431 return (error); 2432 cvtnstat(&sb, &nsb); 2433 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2434 return (error); 2435 } 2436 2437 /* 2438 * NetBSD lstat. Get file status; this version does not follow links. 2439 */ 2440 #ifndef _SYS_SYSPROTO_H_ 2441 struct lstat_args { 2442 char *path; 2443 struct stat *ub; 2444 }; 2445 #endif 2446 int 2447 nlstat(td, uap) 2448 struct thread *td; 2449 register struct nlstat_args /* { 2450 char *path; 2451 struct nstat *ub; 2452 } */ *uap; 2453 { 2454 struct stat sb; 2455 struct nstat nsb; 2456 int error; 2457 2458 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2459 if (error) 2460 return (error); 2461 cvtnstat(&sb, &nsb); 2462 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2463 return (error); 2464 } 2465 2466 /* 2467 * Get configurable pathname variables. 2468 */ 2469 #ifndef _SYS_SYSPROTO_H_ 2470 struct pathconf_args { 2471 char *path; 2472 int name; 2473 }; 2474 #endif 2475 int 2476 pathconf(td, uap) 2477 struct thread *td; 2478 register struct pathconf_args /* { 2479 char *path; 2480 int name; 2481 } */ *uap; 2482 { 2483 2484 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name)); 2485 } 2486 2487 int 2488 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name) 2489 { 2490 struct nameidata nd; 2491 int error, vfslocked; 2492 2493 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2494 pathseg, path, td); 2495 if ((error = namei(&nd)) != 0) 2496 return (error); 2497 vfslocked = NDHASGIANT(&nd); 2498 NDFREE(&nd, NDF_ONLY_PNBUF); 2499 2500 /* If asynchronous I/O is available, it works for all files. */ 2501 if (name == _PC_ASYNC_IO) 2502 td->td_retval[0] = async_io_version; 2503 else 2504 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval); 2505 vput(nd.ni_vp); 2506 VFS_UNLOCK_GIANT(vfslocked); 2507 return (error); 2508 } 2509 2510 /* 2511 * Return target name of a symbolic link. 2512 */ 2513 #ifndef _SYS_SYSPROTO_H_ 2514 struct readlink_args { 2515 char *path; 2516 char *buf; 2517 size_t count; 2518 }; 2519 #endif 2520 int 2521 readlink(td, uap) 2522 struct thread *td; 2523 register struct readlink_args /* { 2524 char *path; 2525 char *buf; 2526 size_t count; 2527 } */ *uap; 2528 { 2529 2530 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, 2531 UIO_USERSPACE, uap->count)); 2532 } 2533 #ifndef _SYS_SYSPROTO_H_ 2534 struct readlinkat_args { 2535 int fd; 2536 char *path; 2537 char *buf; 2538 size_t bufsize; 2539 }; 2540 #endif 2541 int 2542 readlinkat(struct thread *td, struct readlinkat_args *uap) 2543 { 2544 2545 return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, 2546 uap->buf, UIO_USERSPACE, uap->bufsize)); 2547 } 2548 2549 int 2550 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, 2551 enum uio_seg bufseg, size_t count) 2552 { 2553 2554 return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, 2555 count)); 2556 } 2557 2558 int 2559 kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2560 char *buf, enum uio_seg bufseg, size_t count) 2561 { 2562 struct vnode *vp; 2563 struct iovec aiov; 2564 struct uio auio; 2565 int error; 2566 struct nameidata nd; 2567 int vfslocked; 2568 2569 NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 2570 pathseg, path, fd, td); 2571 2572 if ((error = namei(&nd)) != 0) 2573 return (error); 2574 NDFREE(&nd, NDF_ONLY_PNBUF); 2575 vfslocked = NDHASGIANT(&nd); 2576 vp = nd.ni_vp; 2577 #ifdef MAC 2578 error = mac_vnode_check_readlink(td->td_ucred, vp); 2579 if (error) { 2580 vput(vp); 2581 VFS_UNLOCK_GIANT(vfslocked); 2582 return (error); 2583 } 2584 #endif 2585 if (vp->v_type != VLNK) 2586 error = EINVAL; 2587 else { 2588 aiov.iov_base = buf; 2589 aiov.iov_len = count; 2590 auio.uio_iov = &aiov; 2591 auio.uio_iovcnt = 1; 2592 auio.uio_offset = 0; 2593 auio.uio_rw = UIO_READ; 2594 auio.uio_segflg = bufseg; 2595 auio.uio_td = td; 2596 auio.uio_resid = count; 2597 error = VOP_READLINK(vp, &auio, td->td_ucred); 2598 } 2599 vput(vp); 2600 VFS_UNLOCK_GIANT(vfslocked); 2601 td->td_retval[0] = count - auio.uio_resid; 2602 return (error); 2603 } 2604 2605 /* 2606 * Common implementation code for chflags() and fchflags(). 2607 */ 2608 static int 2609 setfflags(td, vp, flags) 2610 struct thread *td; 2611 struct vnode *vp; 2612 int flags; 2613 { 2614 int error; 2615 struct mount *mp; 2616 struct vattr vattr; 2617 2618 /* 2619 * Prevent non-root users from setting flags on devices. When 2620 * a device is reused, users can retain ownership of the device 2621 * if they are allowed to set flags and programs assume that 2622 * chown can't fail when done as root. 2623 */ 2624 if (vp->v_type == VCHR || vp->v_type == VBLK) { 2625 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); 2626 if (error) 2627 return (error); 2628 } 2629 2630 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2631 return (error); 2632 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2633 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2634 VATTR_NULL(&vattr); 2635 vattr.va_flags = flags; 2636 #ifdef MAC 2637 error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); 2638 if (error == 0) 2639 #endif 2640 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2641 VOP_UNLOCK(vp, 0); 2642 vn_finished_write(mp); 2643 return (error); 2644 } 2645 2646 /* 2647 * Change flags of a file given a path name. 2648 */ 2649 #ifndef _SYS_SYSPROTO_H_ 2650 struct chflags_args { 2651 char *path; 2652 int flags; 2653 }; 2654 #endif 2655 int 2656 chflags(td, uap) 2657 struct thread *td; 2658 register struct chflags_args /* { 2659 char *path; 2660 int flags; 2661 } */ *uap; 2662 { 2663 int error; 2664 struct nameidata nd; 2665 int vfslocked; 2666 2667 AUDIT_ARG(fflags, uap->flags); 2668 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2669 uap->path, td); 2670 if ((error = namei(&nd)) != 0) 2671 return (error); 2672 NDFREE(&nd, NDF_ONLY_PNBUF); 2673 vfslocked = NDHASGIANT(&nd); 2674 error = setfflags(td, nd.ni_vp, uap->flags); 2675 vrele(nd.ni_vp); 2676 VFS_UNLOCK_GIANT(vfslocked); 2677 return (error); 2678 } 2679 2680 /* 2681 * Same as chflags() but doesn't follow symlinks. 2682 */ 2683 int 2684 lchflags(td, uap) 2685 struct thread *td; 2686 register struct lchflags_args /* { 2687 char *path; 2688 int flags; 2689 } */ *uap; 2690 { 2691 int error; 2692 struct nameidata nd; 2693 int vfslocked; 2694 2695 AUDIT_ARG(fflags, uap->flags); 2696 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2697 uap->path, td); 2698 if ((error = namei(&nd)) != 0) 2699 return (error); 2700 vfslocked = NDHASGIANT(&nd); 2701 NDFREE(&nd, NDF_ONLY_PNBUF); 2702 error = setfflags(td, nd.ni_vp, uap->flags); 2703 vrele(nd.ni_vp); 2704 VFS_UNLOCK_GIANT(vfslocked); 2705 return (error); 2706 } 2707 2708 /* 2709 * Change flags of a file given a file descriptor. 2710 */ 2711 #ifndef _SYS_SYSPROTO_H_ 2712 struct fchflags_args { 2713 int fd; 2714 int flags; 2715 }; 2716 #endif 2717 int 2718 fchflags(td, uap) 2719 struct thread *td; 2720 register struct fchflags_args /* { 2721 int fd; 2722 int flags; 2723 } */ *uap; 2724 { 2725 struct file *fp; 2726 int vfslocked; 2727 int error; 2728 2729 AUDIT_ARG(fd, uap->fd); 2730 AUDIT_ARG(fflags, uap->flags); 2731 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2732 return (error); 2733 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2734 #ifdef AUDIT 2735 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 2736 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2737 VOP_UNLOCK(fp->f_vnode, 0); 2738 #endif 2739 error = setfflags(td, fp->f_vnode, uap->flags); 2740 VFS_UNLOCK_GIANT(vfslocked); 2741 fdrop(fp, td); 2742 return (error); 2743 } 2744 2745 /* 2746 * Common implementation code for chmod(), lchmod() and fchmod(). 2747 */ 2748 static int 2749 setfmode(td, vp, mode) 2750 struct thread *td; 2751 struct vnode *vp; 2752 int mode; 2753 { 2754 int error; 2755 struct mount *mp; 2756 struct vattr vattr; 2757 2758 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2759 return (error); 2760 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2761 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2762 VATTR_NULL(&vattr); 2763 vattr.va_mode = mode & ALLPERMS; 2764 #ifdef MAC 2765 error = mac_vnode_check_setmode(td->td_ucred, vp, vattr.va_mode); 2766 if (error == 0) 2767 #endif 2768 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2769 VOP_UNLOCK(vp, 0); 2770 vn_finished_write(mp); 2771 return (error); 2772 } 2773 2774 /* 2775 * Change mode of a file given path name. 2776 */ 2777 #ifndef _SYS_SYSPROTO_H_ 2778 struct chmod_args { 2779 char *path; 2780 int mode; 2781 }; 2782 #endif 2783 int 2784 chmod(td, uap) 2785 struct thread *td; 2786 register struct chmod_args /* { 2787 char *path; 2788 int mode; 2789 } */ *uap; 2790 { 2791 2792 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); 2793 } 2794 2795 #ifndef _SYS_SYSPROTO_H_ 2796 struct fchmodat_args { 2797 int dirfd; 2798 char *path; 2799 mode_t mode; 2800 int flag; 2801 } 2802 #endif 2803 int 2804 fchmodat(struct thread *td, struct fchmodat_args *uap) 2805 { 2806 int flag = uap->flag; 2807 int fd = uap->fd; 2808 char *path = uap->path; 2809 mode_t mode = uap->mode; 2810 2811 if (flag & ~AT_SYMLINK_NOFOLLOW) 2812 return (EINVAL); 2813 2814 return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); 2815 } 2816 2817 int 2818 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2819 { 2820 2821 return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); 2822 } 2823 2824 /* 2825 * Change mode of a file given path name (don't follow links.) 2826 */ 2827 #ifndef _SYS_SYSPROTO_H_ 2828 struct lchmod_args { 2829 char *path; 2830 int mode; 2831 }; 2832 #endif 2833 int 2834 lchmod(td, uap) 2835 struct thread *td; 2836 register struct lchmod_args /* { 2837 char *path; 2838 int mode; 2839 } */ *uap; 2840 { 2841 2842 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 2843 uap->mode, AT_SYMLINK_NOFOLLOW)); 2844 } 2845 2846 2847 int 2848 kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2849 mode_t mode, int flag) 2850 { 2851 int error; 2852 struct nameidata nd; 2853 int vfslocked; 2854 int follow; 2855 2856 AUDIT_ARG(mode, mode); 2857 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 2858 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 2859 fd, td); 2860 if ((error = namei(&nd)) != 0) 2861 return (error); 2862 vfslocked = NDHASGIANT(&nd); 2863 NDFREE(&nd, NDF_ONLY_PNBUF); 2864 error = setfmode(td, nd.ni_vp, mode); 2865 vrele(nd.ni_vp); 2866 VFS_UNLOCK_GIANT(vfslocked); 2867 return (error); 2868 } 2869 2870 /* 2871 * Change mode of a file given a file descriptor. 2872 */ 2873 #ifndef _SYS_SYSPROTO_H_ 2874 struct fchmod_args { 2875 int fd; 2876 int mode; 2877 }; 2878 #endif 2879 int 2880 fchmod(td, uap) 2881 struct thread *td; 2882 register struct fchmod_args /* { 2883 int fd; 2884 int mode; 2885 } */ *uap; 2886 { 2887 struct file *fp; 2888 int vfslocked; 2889 int error; 2890 2891 AUDIT_ARG(fd, uap->fd); 2892 AUDIT_ARG(mode, uap->mode); 2893 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2894 return (error); 2895 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2896 #ifdef AUDIT 2897 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 2898 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2899 VOP_UNLOCK(fp->f_vnode, 0); 2900 #endif 2901 error = setfmode(td, fp->f_vnode, uap->mode); 2902 VFS_UNLOCK_GIANT(vfslocked); 2903 fdrop(fp, td); 2904 return (error); 2905 } 2906 2907 /* 2908 * Common implementation for chown(), lchown(), and fchown() 2909 */ 2910 static int 2911 setfown(td, vp, uid, gid) 2912 struct thread *td; 2913 struct vnode *vp; 2914 uid_t uid; 2915 gid_t gid; 2916 { 2917 int error; 2918 struct mount *mp; 2919 struct vattr vattr; 2920 2921 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2922 return (error); 2923 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2924 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2925 VATTR_NULL(&vattr); 2926 vattr.va_uid = uid; 2927 vattr.va_gid = gid; 2928 #ifdef MAC 2929 error = mac_vnode_check_setowner(td->td_ucred, vp, vattr.va_uid, 2930 vattr.va_gid); 2931 if (error == 0) 2932 #endif 2933 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2934 VOP_UNLOCK(vp, 0); 2935 vn_finished_write(mp); 2936 return (error); 2937 } 2938 2939 /* 2940 * Set ownership given a path name. 2941 */ 2942 #ifndef _SYS_SYSPROTO_H_ 2943 struct chown_args { 2944 char *path; 2945 int uid; 2946 int gid; 2947 }; 2948 #endif 2949 int 2950 chown(td, uap) 2951 struct thread *td; 2952 register struct chown_args /* { 2953 char *path; 2954 int uid; 2955 int gid; 2956 } */ *uap; 2957 { 2958 2959 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 2960 } 2961 2962 #ifndef _SYS_SYSPROTO_H_ 2963 struct fchownat_args { 2964 int fd; 2965 const char * path; 2966 uid_t uid; 2967 gid_t gid; 2968 int flag; 2969 }; 2970 #endif 2971 int 2972 fchownat(struct thread *td, struct fchownat_args *uap) 2973 { 2974 int flag; 2975 2976 flag = uap->flag; 2977 if (flag & ~AT_SYMLINK_NOFOLLOW) 2978 return (EINVAL); 2979 2980 return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, 2981 uap->gid, uap->flag)); 2982 } 2983 2984 int 2985 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 2986 int gid) 2987 { 2988 2989 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); 2990 } 2991 2992 int 2993 kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2994 int uid, int gid, int flag) 2995 { 2996 struct nameidata nd; 2997 int error, vfslocked, follow; 2998 2999 AUDIT_ARG(owner, uid, gid); 3000 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 3001 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 3002 fd, td); 3003 3004 if ((error = namei(&nd)) != 0) 3005 return (error); 3006 vfslocked = NDHASGIANT(&nd); 3007 NDFREE(&nd, NDF_ONLY_PNBUF); 3008 error = setfown(td, nd.ni_vp, uid, gid); 3009 vrele(nd.ni_vp); 3010 VFS_UNLOCK_GIANT(vfslocked); 3011 return (error); 3012 } 3013 3014 /* 3015 * Set ownership given a path name, do not cross symlinks. 3016 */ 3017 #ifndef _SYS_SYSPROTO_H_ 3018 struct lchown_args { 3019 char *path; 3020 int uid; 3021 int gid; 3022 }; 3023 #endif 3024 int 3025 lchown(td, uap) 3026 struct thread *td; 3027 register struct lchown_args /* { 3028 char *path; 3029 int uid; 3030 int gid; 3031 } */ *uap; 3032 { 3033 3034 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 3035 } 3036 3037 int 3038 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3039 int gid) 3040 { 3041 3042 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 3043 AT_SYMLINK_NOFOLLOW)); 3044 } 3045 3046 /* 3047 * Set ownership given a file descriptor. 3048 */ 3049 #ifndef _SYS_SYSPROTO_H_ 3050 struct fchown_args { 3051 int fd; 3052 int uid; 3053 int gid; 3054 }; 3055 #endif 3056 int 3057 fchown(td, uap) 3058 struct thread *td; 3059 register struct fchown_args /* { 3060 int fd; 3061 int uid; 3062 int gid; 3063 } */ *uap; 3064 { 3065 struct file *fp; 3066 int vfslocked; 3067 int error; 3068 3069 AUDIT_ARG(fd, uap->fd); 3070 AUDIT_ARG(owner, uap->uid, uap->gid); 3071 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3072 return (error); 3073 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3074 #ifdef AUDIT 3075 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 3076 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3077 VOP_UNLOCK(fp->f_vnode, 0); 3078 #endif 3079 error = setfown(td, fp->f_vnode, uap->uid, uap->gid); 3080 VFS_UNLOCK_GIANT(vfslocked); 3081 fdrop(fp, td); 3082 return (error); 3083 } 3084 3085 /* 3086 * Common implementation code for utimes(), lutimes(), and futimes(). 3087 */ 3088 static int 3089 getutimes(usrtvp, tvpseg, tsp) 3090 const struct timeval *usrtvp; 3091 enum uio_seg tvpseg; 3092 struct timespec *tsp; 3093 { 3094 struct timeval tv[2]; 3095 const struct timeval *tvp; 3096 int error; 3097 3098 if (usrtvp == NULL) { 3099 microtime(&tv[0]); 3100 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 3101 tsp[1] = tsp[0]; 3102 } else { 3103 if (tvpseg == UIO_SYSSPACE) { 3104 tvp = usrtvp; 3105 } else { 3106 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) 3107 return (error); 3108 tvp = tv; 3109 } 3110 3111 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || 3112 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) 3113 return (EINVAL); 3114 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 3115 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 3116 } 3117 return (0); 3118 } 3119 3120 /* 3121 * Common implementation code for utimes(), lutimes(), and futimes(). 3122 */ 3123 static int 3124 setutimes(td, vp, ts, numtimes, nullflag) 3125 struct thread *td; 3126 struct vnode *vp; 3127 const struct timespec *ts; 3128 int numtimes; 3129 int nullflag; 3130 { 3131 int error, setbirthtime; 3132 struct mount *mp; 3133 struct vattr vattr; 3134 3135 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3136 return (error); 3137 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3138 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3139 setbirthtime = 0; 3140 if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && 3141 timespeccmp(&ts[1], &vattr.va_birthtime, < )) 3142 setbirthtime = 1; 3143 VATTR_NULL(&vattr); 3144 vattr.va_atime = ts[0]; 3145 vattr.va_mtime = ts[1]; 3146 if (setbirthtime) 3147 vattr.va_birthtime = ts[1]; 3148 if (numtimes > 2) 3149 vattr.va_birthtime = ts[2]; 3150 if (nullflag) 3151 vattr.va_vaflags |= VA_UTIMES_NULL; 3152 #ifdef MAC 3153 error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, 3154 vattr.va_mtime); 3155 #endif 3156 if (error == 0) 3157 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3158 VOP_UNLOCK(vp, 0); 3159 vn_finished_write(mp); 3160 return (error); 3161 } 3162 3163 /* 3164 * Set the access and modification times of a file. 3165 */ 3166 #ifndef _SYS_SYSPROTO_H_ 3167 struct utimes_args { 3168 char *path; 3169 struct timeval *tptr; 3170 }; 3171 #endif 3172 int 3173 utimes(td, uap) 3174 struct thread *td; 3175 register struct utimes_args /* { 3176 char *path; 3177 struct timeval *tptr; 3178 } */ *uap; 3179 { 3180 3181 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3182 UIO_USERSPACE)); 3183 } 3184 3185 #ifndef _SYS_SYSPROTO_H_ 3186 struct futimesat_args { 3187 int fd; 3188 const char * path; 3189 const struct timeval * times; 3190 }; 3191 #endif 3192 int 3193 futimesat(struct thread *td, struct futimesat_args *uap) 3194 { 3195 3196 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 3197 uap->times, UIO_USERSPACE)); 3198 } 3199 3200 int 3201 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, 3202 struct timeval *tptr, enum uio_seg tptrseg) 3203 { 3204 3205 return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); 3206 } 3207 3208 int 3209 kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3210 struct timeval *tptr, enum uio_seg tptrseg) 3211 { 3212 struct nameidata nd; 3213 struct timespec ts[2]; 3214 int error, vfslocked; 3215 3216 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3217 return (error); 3218 NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, 3219 fd, td); 3220 3221 if ((error = namei(&nd)) != 0) 3222 return (error); 3223 vfslocked = NDHASGIANT(&nd); 3224 NDFREE(&nd, NDF_ONLY_PNBUF); 3225 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3226 vrele(nd.ni_vp); 3227 VFS_UNLOCK_GIANT(vfslocked); 3228 return (error); 3229 } 3230 3231 /* 3232 * Set the access and modification times of a file. 3233 */ 3234 #ifndef _SYS_SYSPROTO_H_ 3235 struct lutimes_args { 3236 char *path; 3237 struct timeval *tptr; 3238 }; 3239 #endif 3240 int 3241 lutimes(td, uap) 3242 struct thread *td; 3243 register struct lutimes_args /* { 3244 char *path; 3245 struct timeval *tptr; 3246 } */ *uap; 3247 { 3248 3249 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3250 UIO_USERSPACE)); 3251 } 3252 3253 int 3254 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, 3255 struct timeval *tptr, enum uio_seg tptrseg) 3256 { 3257 struct timespec ts[2]; 3258 int error; 3259 struct nameidata nd; 3260 int vfslocked; 3261 3262 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3263 return (error); 3264 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3265 if ((error = namei(&nd)) != 0) 3266 return (error); 3267 vfslocked = NDHASGIANT(&nd); 3268 NDFREE(&nd, NDF_ONLY_PNBUF); 3269 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3270 vrele(nd.ni_vp); 3271 VFS_UNLOCK_GIANT(vfslocked); 3272 return (error); 3273 } 3274 3275 /* 3276 * Set the access and modification times of a file. 3277 */ 3278 #ifndef _SYS_SYSPROTO_H_ 3279 struct futimes_args { 3280 int fd; 3281 struct timeval *tptr; 3282 }; 3283 #endif 3284 int 3285 futimes(td, uap) 3286 struct thread *td; 3287 register struct futimes_args /* { 3288 int fd; 3289 struct timeval *tptr; 3290 } */ *uap; 3291 { 3292 3293 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); 3294 } 3295 3296 int 3297 kern_futimes(struct thread *td, int fd, struct timeval *tptr, 3298 enum uio_seg tptrseg) 3299 { 3300 struct timespec ts[2]; 3301 struct file *fp; 3302 int vfslocked; 3303 int error; 3304 3305 AUDIT_ARG(fd, fd); 3306 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3307 return (error); 3308 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 3309 return (error); 3310 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3311 #ifdef AUDIT 3312 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY); 3313 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3314 VOP_UNLOCK(fp->f_vnode, 0); 3315 #endif 3316 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); 3317 VFS_UNLOCK_GIANT(vfslocked); 3318 fdrop(fp, td); 3319 return (error); 3320 } 3321 3322 /* 3323 * Truncate a file given its path name. 3324 */ 3325 #ifndef _SYS_SYSPROTO_H_ 3326 struct truncate_args { 3327 char *path; 3328 int pad; 3329 off_t length; 3330 }; 3331 #endif 3332 int 3333 truncate(td, uap) 3334 struct thread *td; 3335 register struct truncate_args /* { 3336 char *path; 3337 int pad; 3338 off_t length; 3339 } */ *uap; 3340 { 3341 3342 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); 3343 } 3344 3345 int 3346 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) 3347 { 3348 struct mount *mp; 3349 struct vnode *vp; 3350 struct vattr vattr; 3351 int error; 3352 struct nameidata nd; 3353 int vfslocked; 3354 3355 if (length < 0) 3356 return(EINVAL); 3357 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3358 if ((error = namei(&nd)) != 0) 3359 return (error); 3360 vfslocked = NDHASGIANT(&nd); 3361 vp = nd.ni_vp; 3362 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 3363 vrele(vp); 3364 VFS_UNLOCK_GIANT(vfslocked); 3365 return (error); 3366 } 3367 NDFREE(&nd, NDF_ONLY_PNBUF); 3368 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3369 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3370 if (vp->v_type == VDIR) 3371 error = EISDIR; 3372 #ifdef MAC 3373 else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { 3374 } 3375 #endif 3376 else if ((error = vn_writechk(vp)) == 0 && 3377 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { 3378 VATTR_NULL(&vattr); 3379 vattr.va_size = length; 3380 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3381 } 3382 vput(vp); 3383 vn_finished_write(mp); 3384 VFS_UNLOCK_GIANT(vfslocked); 3385 return (error); 3386 } 3387 3388 #if defined(COMPAT_43) 3389 /* 3390 * Truncate a file given its path name. 3391 */ 3392 #ifndef _SYS_SYSPROTO_H_ 3393 struct otruncate_args { 3394 char *path; 3395 long length; 3396 }; 3397 #endif 3398 int 3399 otruncate(td, uap) 3400 struct thread *td; 3401 register struct otruncate_args /* { 3402 char *path; 3403 long length; 3404 } */ *uap; 3405 { 3406 struct truncate_args /* { 3407 char *path; 3408 int pad; 3409 off_t length; 3410 } */ nuap; 3411 3412 nuap.path = uap->path; 3413 nuap.length = uap->length; 3414 return (truncate(td, &nuap)); 3415 } 3416 #endif /* COMPAT_43 */ 3417 3418 /* Versions with the pad argument */ 3419 int 3420 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) 3421 { 3422 struct truncate_args ouap; 3423 3424 ouap.path = uap->path; 3425 ouap.length = uap->length; 3426 return (truncate(td, &ouap)); 3427 } 3428 3429 int 3430 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) 3431 { 3432 struct ftruncate_args ouap; 3433 3434 ouap.fd = uap->fd; 3435 ouap.length = uap->length; 3436 return (ftruncate(td, &ouap)); 3437 } 3438 3439 /* 3440 * Sync an open file. 3441 */ 3442 #ifndef _SYS_SYSPROTO_H_ 3443 struct fsync_args { 3444 int fd; 3445 }; 3446 #endif 3447 int 3448 fsync(td, uap) 3449 struct thread *td; 3450 struct fsync_args /* { 3451 int fd; 3452 } */ *uap; 3453 { 3454 struct vnode *vp; 3455 struct mount *mp; 3456 struct file *fp; 3457 int vfslocked; 3458 int error; 3459 3460 AUDIT_ARG(fd, uap->fd); 3461 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3462 return (error); 3463 vp = fp->f_vnode; 3464 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3465 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3466 goto drop; 3467 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3468 AUDIT_ARG(vnode, vp, ARG_VNODE1); 3469 if (vp->v_object != NULL) { 3470 VM_OBJECT_LOCK(vp->v_object); 3471 vm_object_page_clean(vp->v_object, 0, 0, 0); 3472 VM_OBJECT_UNLOCK(vp->v_object); 3473 } 3474 error = VOP_FSYNC(vp, MNT_WAIT, td); 3475 3476 VOP_UNLOCK(vp, 0); 3477 vn_finished_write(mp); 3478 drop: 3479 VFS_UNLOCK_GIANT(vfslocked); 3480 fdrop(fp, td); 3481 return (error); 3482 } 3483 3484 /* 3485 * Rename files. Source and destination must either both be directories, or 3486 * both not be directories. If target is a directory, it must be empty. 3487 */ 3488 #ifndef _SYS_SYSPROTO_H_ 3489 struct rename_args { 3490 char *from; 3491 char *to; 3492 }; 3493 #endif 3494 int 3495 rename(td, uap) 3496 struct thread *td; 3497 register struct rename_args /* { 3498 char *from; 3499 char *to; 3500 } */ *uap; 3501 { 3502 3503 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); 3504 } 3505 3506 #ifndef _SYS_SYSPROTO_H_ 3507 struct renameat_args { 3508 int oldfd; 3509 char *old; 3510 int newfd; 3511 char *new; 3512 }; 3513 #endif 3514 int 3515 renameat(struct thread *td, struct renameat_args *uap) 3516 { 3517 3518 return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, 3519 UIO_USERSPACE)); 3520 } 3521 3522 int 3523 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) 3524 { 3525 3526 return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); 3527 } 3528 3529 int 3530 kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, 3531 enum uio_seg pathseg) 3532 { 3533 struct mount *mp = NULL; 3534 struct vnode *tvp, *fvp, *tdvp; 3535 struct nameidata fromnd, tond; 3536 int tvfslocked; 3537 int fvfslocked; 3538 int error; 3539 3540 bwillwrite(); 3541 #ifdef MAC 3542 NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | 3543 AUDITVNODE1, pathseg, old, oldfd, td); 3544 #else 3545 NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | 3546 AUDITVNODE1, pathseg, old, oldfd, td); 3547 #endif 3548 3549 if ((error = namei(&fromnd)) != 0) 3550 return (error); 3551 fvfslocked = NDHASGIANT(&fromnd); 3552 tvfslocked = 0; 3553 #ifdef MAC 3554 error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp, 3555 fromnd.ni_vp, &fromnd.ni_cnd); 3556 VOP_UNLOCK(fromnd.ni_dvp, 0); 3557 if (fromnd.ni_dvp != fromnd.ni_vp) 3558 VOP_UNLOCK(fromnd.ni_vp, 0); 3559 #endif 3560 fvp = fromnd.ni_vp; 3561 if (error == 0) 3562 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); 3563 if (error != 0) { 3564 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3565 vrele(fromnd.ni_dvp); 3566 vrele(fvp); 3567 goto out1; 3568 } 3569 NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | 3570 MPSAFE | AUDITVNODE2, pathseg, new, newfd, td); 3571 if (fromnd.ni_vp->v_type == VDIR) 3572 tond.ni_cnd.cn_flags |= WILLBEDIR; 3573 if ((error = namei(&tond)) != 0) { 3574 /* Translate error code for rename("dir1", "dir2/."). */ 3575 if (error == EISDIR && fvp->v_type == VDIR) 3576 error = EINVAL; 3577 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3578 vrele(fromnd.ni_dvp); 3579 vrele(fvp); 3580 vn_finished_write(mp); 3581 goto out1; 3582 } 3583 tvfslocked = NDHASGIANT(&tond); 3584 tdvp = tond.ni_dvp; 3585 tvp = tond.ni_vp; 3586 if (tvp != NULL) { 3587 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 3588 error = ENOTDIR; 3589 goto out; 3590 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 3591 error = EISDIR; 3592 goto out; 3593 } 3594 } 3595 if (fvp == tdvp) { 3596 error = EINVAL; 3597 goto out; 3598 } 3599 /* 3600 * If the source is the same as the destination (that is, if they 3601 * are links to the same vnode), then there is nothing to do. 3602 */ 3603 if (fvp == tvp) 3604 error = -1; 3605 #ifdef MAC 3606 else 3607 error = mac_vnode_check_rename_to(td->td_ucred, tdvp, 3608 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); 3609 #endif 3610 out: 3611 if (!error) { 3612 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); 3613 if (fromnd.ni_dvp != tdvp) { 3614 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3615 } 3616 if (tvp) { 3617 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); 3618 } 3619 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 3620 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 3621 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3622 NDFREE(&tond, NDF_ONLY_PNBUF); 3623 } else { 3624 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3625 NDFREE(&tond, NDF_ONLY_PNBUF); 3626 if (tvp) 3627 vput(tvp); 3628 if (tdvp == tvp) 3629 vrele(tdvp); 3630 else 3631 vput(tdvp); 3632 vrele(fromnd.ni_dvp); 3633 vrele(fvp); 3634 } 3635 vrele(tond.ni_startdir); 3636 vn_finished_write(mp); 3637 out1: 3638 if (fromnd.ni_startdir) 3639 vrele(fromnd.ni_startdir); 3640 VFS_UNLOCK_GIANT(fvfslocked); 3641 VFS_UNLOCK_GIANT(tvfslocked); 3642 if (error == -1) 3643 return (0); 3644 return (error); 3645 } 3646 3647 /* 3648 * Make a directory file. 3649 */ 3650 #ifndef _SYS_SYSPROTO_H_ 3651 struct mkdir_args { 3652 char *path; 3653 int mode; 3654 }; 3655 #endif 3656 int 3657 mkdir(td, uap) 3658 struct thread *td; 3659 register struct mkdir_args /* { 3660 char *path; 3661 int mode; 3662 } */ *uap; 3663 { 3664 3665 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); 3666 } 3667 3668 #ifndef _SYS_SYSPROTO_H_ 3669 struct mkdirat_args { 3670 int fd; 3671 char *path; 3672 mode_t mode; 3673 }; 3674 #endif 3675 int 3676 mkdirat(struct thread *td, struct mkdirat_args *uap) 3677 { 3678 3679 return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); 3680 } 3681 3682 int 3683 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) 3684 { 3685 3686 return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); 3687 } 3688 3689 int 3690 kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, 3691 int mode) 3692 { 3693 struct mount *mp; 3694 struct vnode *vp; 3695 struct vattr vattr; 3696 int error; 3697 struct nameidata nd; 3698 int vfslocked; 3699 3700 AUDIT_ARG(mode, mode); 3701 restart: 3702 bwillwrite(); 3703 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 3704 segflg, path, fd, td); 3705 nd.ni_cnd.cn_flags |= WILLBEDIR; 3706 if ((error = namei(&nd)) != 0) 3707 return (error); 3708 vfslocked = NDHASGIANT(&nd); 3709 vp = nd.ni_vp; 3710 if (vp != NULL) { 3711 NDFREE(&nd, NDF_ONLY_PNBUF); 3712 /* 3713 * XXX namei called with LOCKPARENT but not LOCKLEAF has 3714 * the strange behaviour of leaving the vnode unlocked 3715 * if the target is the same vnode as the parent. 3716 */ 3717 if (vp == nd.ni_dvp) 3718 vrele(nd.ni_dvp); 3719 else 3720 vput(nd.ni_dvp); 3721 vrele(vp); 3722 VFS_UNLOCK_GIANT(vfslocked); 3723 return (EEXIST); 3724 } 3725 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3726 NDFREE(&nd, NDF_ONLY_PNBUF); 3727 vput(nd.ni_dvp); 3728 VFS_UNLOCK_GIANT(vfslocked); 3729 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3730 return (error); 3731 goto restart; 3732 } 3733 VATTR_NULL(&vattr); 3734 vattr.va_type = VDIR; 3735 FILEDESC_SLOCK(td->td_proc->p_fd); 3736 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; 3737 FILEDESC_SUNLOCK(td->td_proc->p_fd); 3738 #ifdef MAC 3739 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 3740 &vattr); 3741 if (error) 3742 goto out; 3743 #endif 3744 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3745 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 3746 #ifdef MAC 3747 out: 3748 #endif 3749 NDFREE(&nd, NDF_ONLY_PNBUF); 3750 vput(nd.ni_dvp); 3751 if (!error) 3752 vput(nd.ni_vp); 3753 vn_finished_write(mp); 3754 VFS_UNLOCK_GIANT(vfslocked); 3755 return (error); 3756 } 3757 3758 /* 3759 * Remove a directory file. 3760 */ 3761 #ifndef _SYS_SYSPROTO_H_ 3762 struct rmdir_args { 3763 char *path; 3764 }; 3765 #endif 3766 int 3767 rmdir(td, uap) 3768 struct thread *td; 3769 struct rmdir_args /* { 3770 char *path; 3771 } */ *uap; 3772 { 3773 3774 return (kern_rmdir(td, uap->path, UIO_USERSPACE)); 3775 } 3776 3777 int 3778 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) 3779 { 3780 3781 return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); 3782 } 3783 3784 int 3785 kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 3786 { 3787 struct mount *mp; 3788 struct vnode *vp; 3789 int error; 3790 struct nameidata nd; 3791 int vfslocked; 3792 3793 restart: 3794 bwillwrite(); 3795 NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, 3796 pathseg, path, fd, td); 3797 if ((error = namei(&nd)) != 0) 3798 return (error); 3799 vfslocked = NDHASGIANT(&nd); 3800 vp = nd.ni_vp; 3801 if (vp->v_type != VDIR) { 3802 error = ENOTDIR; 3803 goto out; 3804 } 3805 /* 3806 * No rmdir "." please. 3807 */ 3808 if (nd.ni_dvp == vp) { 3809 error = EINVAL; 3810 goto out; 3811 } 3812 /* 3813 * The root of a mounted filesystem cannot be deleted. 3814 */ 3815 if (vp->v_vflag & VV_ROOT) { 3816 error = EBUSY; 3817 goto out; 3818 } 3819 #ifdef MAC 3820 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 3821 &nd.ni_cnd); 3822 if (error) 3823 goto out; 3824 #endif 3825 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3826 NDFREE(&nd, NDF_ONLY_PNBUF); 3827 vput(vp); 3828 if (nd.ni_dvp == vp) 3829 vrele(nd.ni_dvp); 3830 else 3831 vput(nd.ni_dvp); 3832 VFS_UNLOCK_GIANT(vfslocked); 3833 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3834 return (error); 3835 goto restart; 3836 } 3837 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3838 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3839 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 3840 vn_finished_write(mp); 3841 out: 3842 NDFREE(&nd, NDF_ONLY_PNBUF); 3843 vput(vp); 3844 if (nd.ni_dvp == vp) 3845 vrele(nd.ni_dvp); 3846 else 3847 vput(nd.ni_dvp); 3848 VFS_UNLOCK_GIANT(vfslocked); 3849 return (error); 3850 } 3851 3852 #ifdef COMPAT_43 3853 /* 3854 * Read a block of directory entries in a filesystem independent format. 3855 */ 3856 #ifndef _SYS_SYSPROTO_H_ 3857 struct ogetdirentries_args { 3858 int fd; 3859 char *buf; 3860 u_int count; 3861 long *basep; 3862 }; 3863 #endif 3864 int 3865 ogetdirentries(td, uap) 3866 struct thread *td; 3867 register struct ogetdirentries_args /* { 3868 int fd; 3869 char *buf; 3870 u_int count; 3871 long *basep; 3872 } */ *uap; 3873 { 3874 struct vnode *vp; 3875 struct file *fp; 3876 struct uio auio, kuio; 3877 struct iovec aiov, kiov; 3878 struct dirent *dp, *edp; 3879 caddr_t dirbuf; 3880 int error, eofflag, readcnt, vfslocked; 3881 long loff; 3882 3883 /* XXX arbitrary sanity limit on `count'. */ 3884 if (uap->count > 64 * 1024) 3885 return (EINVAL); 3886 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3887 return (error); 3888 if ((fp->f_flag & FREAD) == 0) { 3889 fdrop(fp, td); 3890 return (EBADF); 3891 } 3892 vp = fp->f_vnode; 3893 unionread: 3894 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3895 if (vp->v_type != VDIR) { 3896 VFS_UNLOCK_GIANT(vfslocked); 3897 fdrop(fp, td); 3898 return (EINVAL); 3899 } 3900 aiov.iov_base = uap->buf; 3901 aiov.iov_len = uap->count; 3902 auio.uio_iov = &aiov; 3903 auio.uio_iovcnt = 1; 3904 auio.uio_rw = UIO_READ; 3905 auio.uio_segflg = UIO_USERSPACE; 3906 auio.uio_td = td; 3907 auio.uio_resid = uap->count; 3908 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3909 loff = auio.uio_offset = fp->f_offset; 3910 #ifdef MAC 3911 error = mac_vnode_check_readdir(td->td_ucred, vp); 3912 if (error) { 3913 VOP_UNLOCK(vp, 0); 3914 VFS_UNLOCK_GIANT(vfslocked); 3915 fdrop(fp, td); 3916 return (error); 3917 } 3918 #endif 3919 # if (BYTE_ORDER != LITTLE_ENDIAN) 3920 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 3921 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 3922 NULL, NULL); 3923 fp->f_offset = auio.uio_offset; 3924 } else 3925 # endif 3926 { 3927 kuio = auio; 3928 kuio.uio_iov = &kiov; 3929 kuio.uio_segflg = UIO_SYSSPACE; 3930 kiov.iov_len = uap->count; 3931 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); 3932 kiov.iov_base = dirbuf; 3933 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 3934 NULL, NULL); 3935 fp->f_offset = kuio.uio_offset; 3936 if (error == 0) { 3937 readcnt = uap->count - kuio.uio_resid; 3938 edp = (struct dirent *)&dirbuf[readcnt]; 3939 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 3940 # if (BYTE_ORDER == LITTLE_ENDIAN) 3941 /* 3942 * The expected low byte of 3943 * dp->d_namlen is our dp->d_type. 3944 * The high MBZ byte of dp->d_namlen 3945 * is our dp->d_namlen. 3946 */ 3947 dp->d_type = dp->d_namlen; 3948 dp->d_namlen = 0; 3949 # else 3950 /* 3951 * The dp->d_type is the high byte 3952 * of the expected dp->d_namlen, 3953 * so must be zero'ed. 3954 */ 3955 dp->d_type = 0; 3956 # endif 3957 if (dp->d_reclen > 0) { 3958 dp = (struct dirent *) 3959 ((char *)dp + dp->d_reclen); 3960 } else { 3961 error = EIO; 3962 break; 3963 } 3964 } 3965 if (dp >= edp) 3966 error = uiomove(dirbuf, readcnt, &auio); 3967 } 3968 FREE(dirbuf, M_TEMP); 3969 } 3970 if (error) { 3971 VOP_UNLOCK(vp, 0); 3972 VFS_UNLOCK_GIANT(vfslocked); 3973 fdrop(fp, td); 3974 return (error); 3975 } 3976 if (uap->count == auio.uio_resid && 3977 (vp->v_vflag & VV_ROOT) && 3978 (vp->v_mount->mnt_flag & MNT_UNION)) { 3979 struct vnode *tvp = vp; 3980 vp = vp->v_mount->mnt_vnodecovered; 3981 VREF(vp); 3982 fp->f_vnode = vp; 3983 fp->f_data = vp; 3984 fp->f_offset = 0; 3985 vput(tvp); 3986 VFS_UNLOCK_GIANT(vfslocked); 3987 goto unionread; 3988 } 3989 VOP_UNLOCK(vp, 0); 3990 VFS_UNLOCK_GIANT(vfslocked); 3991 error = copyout(&loff, uap->basep, sizeof(long)); 3992 fdrop(fp, td); 3993 td->td_retval[0] = uap->count - auio.uio_resid; 3994 return (error); 3995 } 3996 #endif /* COMPAT_43 */ 3997 3998 /* 3999 * Read a block of directory entries in a filesystem independent format. 4000 */ 4001 #ifndef _SYS_SYSPROTO_H_ 4002 struct getdirentries_args { 4003 int fd; 4004 char *buf; 4005 u_int count; 4006 long *basep; 4007 }; 4008 #endif 4009 int 4010 getdirentries(td, uap) 4011 struct thread *td; 4012 register struct getdirentries_args /* { 4013 int fd; 4014 char *buf; 4015 u_int count; 4016 long *basep; 4017 } */ *uap; 4018 { 4019 struct vnode *vp; 4020 struct file *fp; 4021 struct uio auio; 4022 struct iovec aiov; 4023 int vfslocked; 4024 long loff; 4025 int error, eofflag; 4026 4027 AUDIT_ARG(fd, uap->fd); 4028 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 4029 return (error); 4030 if ((fp->f_flag & FREAD) == 0) { 4031 fdrop(fp, td); 4032 return (EBADF); 4033 } 4034 vp = fp->f_vnode; 4035 unionread: 4036 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 4037 if (vp->v_type != VDIR) { 4038 VFS_UNLOCK_GIANT(vfslocked); 4039 error = EINVAL; 4040 goto fail; 4041 } 4042 aiov.iov_base = uap->buf; 4043 aiov.iov_len = uap->count; 4044 auio.uio_iov = &aiov; 4045 auio.uio_iovcnt = 1; 4046 auio.uio_rw = UIO_READ; 4047 auio.uio_segflg = UIO_USERSPACE; 4048 auio.uio_td = td; 4049 auio.uio_resid = uap->count; 4050 /* vn_lock(vp, LK_SHARED | LK_RETRY); */ 4051 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4052 AUDIT_ARG(vnode, vp, ARG_VNODE1); 4053 loff = auio.uio_offset = fp->f_offset; 4054 #ifdef MAC 4055 error = mac_vnode_check_readdir(td->td_ucred, vp); 4056 if (error == 0) 4057 #endif 4058 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, 4059 NULL); 4060 fp->f_offset = auio.uio_offset; 4061 if (error) { 4062 VOP_UNLOCK(vp, 0); 4063 VFS_UNLOCK_GIANT(vfslocked); 4064 goto fail; 4065 } 4066 if (uap->count == auio.uio_resid && 4067 (vp->v_vflag & VV_ROOT) && 4068 (vp->v_mount->mnt_flag & MNT_UNION)) { 4069 struct vnode *tvp = vp; 4070 vp = vp->v_mount->mnt_vnodecovered; 4071 VREF(vp); 4072 fp->f_vnode = vp; 4073 fp->f_data = vp; 4074 fp->f_offset = 0; 4075 vput(tvp); 4076 VFS_UNLOCK_GIANT(vfslocked); 4077 goto unionread; 4078 } 4079 VOP_UNLOCK(vp, 0); 4080 VFS_UNLOCK_GIANT(vfslocked); 4081 if (uap->basep != NULL) { 4082 error = copyout(&loff, uap->basep, sizeof(long)); 4083 } 4084 td->td_retval[0] = uap->count - auio.uio_resid; 4085 fail: 4086 fdrop(fp, td); 4087 return (error); 4088 } 4089 4090 #ifndef _SYS_SYSPROTO_H_ 4091 struct getdents_args { 4092 int fd; 4093 char *buf; 4094 size_t count; 4095 }; 4096 #endif 4097 int 4098 getdents(td, uap) 4099 struct thread *td; 4100 register struct getdents_args /* { 4101 int fd; 4102 char *buf; 4103 u_int count; 4104 } */ *uap; 4105 { 4106 struct getdirentries_args ap; 4107 ap.fd = uap->fd; 4108 ap.buf = uap->buf; 4109 ap.count = uap->count; 4110 ap.basep = NULL; 4111 return (getdirentries(td, &ap)); 4112 } 4113 4114 /* 4115 * Set the mode mask for creation of filesystem nodes. 4116 */ 4117 #ifndef _SYS_SYSPROTO_H_ 4118 struct umask_args { 4119 int newmask; 4120 }; 4121 #endif 4122 int 4123 umask(td, uap) 4124 struct thread *td; 4125 struct umask_args /* { 4126 int newmask; 4127 } */ *uap; 4128 { 4129 register struct filedesc *fdp; 4130 4131 FILEDESC_XLOCK(td->td_proc->p_fd); 4132 fdp = td->td_proc->p_fd; 4133 td->td_retval[0] = fdp->fd_cmask; 4134 fdp->fd_cmask = uap->newmask & ALLPERMS; 4135 FILEDESC_XUNLOCK(td->td_proc->p_fd); 4136 return (0); 4137 } 4138 4139 /* 4140 * Void all references to file by ripping underlying filesystem away from 4141 * vnode. 4142 */ 4143 #ifndef _SYS_SYSPROTO_H_ 4144 struct revoke_args { 4145 char *path; 4146 }; 4147 #endif 4148 int 4149 revoke(td, uap) 4150 struct thread *td; 4151 register struct revoke_args /* { 4152 char *path; 4153 } */ *uap; 4154 { 4155 struct vnode *vp; 4156 struct vattr vattr; 4157 int error; 4158 struct nameidata nd; 4159 int vfslocked; 4160 4161 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4162 UIO_USERSPACE, uap->path, td); 4163 if ((error = namei(&nd)) != 0) 4164 return (error); 4165 vfslocked = NDHASGIANT(&nd); 4166 vp = nd.ni_vp; 4167 NDFREE(&nd, NDF_ONLY_PNBUF); 4168 if (vp->v_type != VCHR) { 4169 error = EINVAL; 4170 goto out; 4171 } 4172 #ifdef MAC 4173 error = mac_vnode_check_revoke(td->td_ucred, vp); 4174 if (error) 4175 goto out; 4176 #endif 4177 error = VOP_GETATTR(vp, &vattr, td->td_ucred); 4178 if (error) 4179 goto out; 4180 if (td->td_ucred->cr_uid != vattr.va_uid) { 4181 error = priv_check(td, PRIV_VFS_ADMIN); 4182 if (error) 4183 goto out; 4184 } 4185 if (vcount(vp) > 1) 4186 VOP_REVOKE(vp, REVOKEALL); 4187 out: 4188 vput(vp); 4189 VFS_UNLOCK_GIANT(vfslocked); 4190 return (error); 4191 } 4192 4193 /* 4194 * Convert a user file descriptor to a kernel file entry. 4195 * A reference on the file entry is held upon returning. 4196 */ 4197 int 4198 getvnode(fdp, fd, fpp) 4199 struct filedesc *fdp; 4200 int fd; 4201 struct file **fpp; 4202 { 4203 int error; 4204 struct file *fp; 4205 4206 fp = NULL; 4207 if (fdp == NULL) 4208 error = EBADF; 4209 else { 4210 FILEDESC_SLOCK(fdp); 4211 if ((u_int)fd >= fdp->fd_nfiles || 4212 (fp = fdp->fd_ofiles[fd]) == NULL) 4213 error = EBADF; 4214 else if (fp->f_vnode == NULL) { 4215 fp = NULL; 4216 error = EINVAL; 4217 } else { 4218 fhold(fp); 4219 error = 0; 4220 } 4221 FILEDESC_SUNLOCK(fdp); 4222 } 4223 *fpp = fp; 4224 return (error); 4225 } 4226 4227 /* 4228 * Get an (NFS) file handle. 4229 */ 4230 #ifndef _SYS_SYSPROTO_H_ 4231 struct lgetfh_args { 4232 char *fname; 4233 fhandle_t *fhp; 4234 }; 4235 #endif 4236 int 4237 lgetfh(td, uap) 4238 struct thread *td; 4239 register struct lgetfh_args *uap; 4240 { 4241 struct nameidata nd; 4242 fhandle_t fh; 4243 register struct vnode *vp; 4244 int vfslocked; 4245 int error; 4246 4247 error = priv_check(td, PRIV_VFS_GETFH); 4248 if (error) 4249 return (error); 4250 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4251 UIO_USERSPACE, uap->fname, td); 4252 error = namei(&nd); 4253 if (error) 4254 return (error); 4255 vfslocked = NDHASGIANT(&nd); 4256 NDFREE(&nd, NDF_ONLY_PNBUF); 4257 vp = nd.ni_vp; 4258 bzero(&fh, sizeof(fh)); 4259 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4260 error = VOP_VPTOFH(vp, &fh.fh_fid); 4261 vput(vp); 4262 VFS_UNLOCK_GIANT(vfslocked); 4263 if (error) 4264 return (error); 4265 error = copyout(&fh, uap->fhp, sizeof (fh)); 4266 return (error); 4267 } 4268 4269 #ifndef _SYS_SYSPROTO_H_ 4270 struct getfh_args { 4271 char *fname; 4272 fhandle_t *fhp; 4273 }; 4274 #endif 4275 int 4276 getfh(td, uap) 4277 struct thread *td; 4278 register struct getfh_args *uap; 4279 { 4280 struct nameidata nd; 4281 fhandle_t fh; 4282 register struct vnode *vp; 4283 int vfslocked; 4284 int error; 4285 4286 error = priv_check(td, PRIV_VFS_GETFH); 4287 if (error) 4288 return (error); 4289 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4290 UIO_USERSPACE, uap->fname, td); 4291 error = namei(&nd); 4292 if (error) 4293 return (error); 4294 vfslocked = NDHASGIANT(&nd); 4295 NDFREE(&nd, NDF_ONLY_PNBUF); 4296 vp = nd.ni_vp; 4297 bzero(&fh, sizeof(fh)); 4298 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4299 error = VOP_VPTOFH(vp, &fh.fh_fid); 4300 vput(vp); 4301 VFS_UNLOCK_GIANT(vfslocked); 4302 if (error) 4303 return (error); 4304 error = copyout(&fh, uap->fhp, sizeof (fh)); 4305 return (error); 4306 } 4307 4308 /* 4309 * syscall for the rpc.lockd to use to translate a NFS file handle into an 4310 * open descriptor. 4311 * 4312 * warning: do not remove the priv_check() call or this becomes one giant 4313 * security hole. 4314 */ 4315 #ifndef _SYS_SYSPROTO_H_ 4316 struct fhopen_args { 4317 const struct fhandle *u_fhp; 4318 int flags; 4319 }; 4320 #endif 4321 int 4322 fhopen(td, uap) 4323 struct thread *td; 4324 struct fhopen_args /* { 4325 const struct fhandle *u_fhp; 4326 int flags; 4327 } */ *uap; 4328 { 4329 struct proc *p = td->td_proc; 4330 struct mount *mp; 4331 struct vnode *vp; 4332 struct fhandle fhp; 4333 struct vattr vat; 4334 struct vattr *vap = &vat; 4335 struct flock lf; 4336 struct file *fp; 4337 register struct filedesc *fdp = p->p_fd; 4338 int fmode, mode, error, type; 4339 struct file *nfp; 4340 int vfslocked; 4341 int indx; 4342 4343 error = priv_check(td, PRIV_VFS_FHOPEN); 4344 if (error) 4345 return (error); 4346 fmode = FFLAGS(uap->flags); 4347 /* why not allow a non-read/write open for our lockd? */ 4348 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 4349 return (EINVAL); 4350 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 4351 if (error) 4352 return(error); 4353 /* find the mount point */ 4354 mp = vfs_getvfs(&fhp.fh_fsid); 4355 if (mp == NULL) 4356 return (ESTALE); 4357 vfslocked = VFS_LOCK_GIANT(mp); 4358 /* now give me my vnode, it gets returned to me locked */ 4359 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 4360 if (error) 4361 goto out; 4362 /* 4363 * from now on we have to make sure not 4364 * to forget about the vnode 4365 * any error that causes an abort must vput(vp) 4366 * just set error = err and 'goto bad;'. 4367 */ 4368 4369 /* 4370 * from vn_open 4371 */ 4372 if (vp->v_type == VLNK) { 4373 error = EMLINK; 4374 goto bad; 4375 } 4376 if (vp->v_type == VSOCK) { 4377 error = EOPNOTSUPP; 4378 goto bad; 4379 } 4380 mode = 0; 4381 if (fmode & (FWRITE | O_TRUNC)) { 4382 if (vp->v_type == VDIR) { 4383 error = EISDIR; 4384 goto bad; 4385 } 4386 error = vn_writechk(vp); 4387 if (error) 4388 goto bad; 4389 mode |= VWRITE; 4390 } 4391 if (fmode & FREAD) 4392 mode |= VREAD; 4393 if (fmode & O_APPEND) 4394 mode |= VAPPEND; 4395 #ifdef MAC 4396 error = mac_vnode_check_open(td->td_ucred, vp, mode); 4397 if (error) 4398 goto bad; 4399 #endif 4400 if (mode) { 4401 error = VOP_ACCESS(vp, mode, td->td_ucred, td); 4402 if (error) 4403 goto bad; 4404 } 4405 if (fmode & O_TRUNC) { 4406 VOP_UNLOCK(vp, 0); /* XXX */ 4407 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) { 4408 vrele(vp); 4409 goto out; 4410 } 4411 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 4412 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ 4413 #ifdef MAC 4414 /* 4415 * We don't yet have fp->f_cred, so use td->td_ucred, which 4416 * should be right. 4417 */ 4418 error = mac_vnode_check_write(td->td_ucred, td->td_ucred, vp); 4419 if (error == 0) { 4420 #endif 4421 VATTR_NULL(vap); 4422 vap->va_size = 0; 4423 error = VOP_SETATTR(vp, vap, td->td_ucred); 4424 #ifdef MAC 4425 } 4426 #endif 4427 vn_finished_write(mp); 4428 if (error) 4429 goto bad; 4430 } 4431 error = VOP_OPEN(vp, fmode, td->td_ucred, td, NULL); 4432 if (error) 4433 goto bad; 4434 4435 if (fmode & FWRITE) 4436 vp->v_writecount++; 4437 4438 /* 4439 * end of vn_open code 4440 */ 4441 4442 if ((error = falloc(td, &nfp, &indx)) != 0) { 4443 if (fmode & FWRITE) 4444 vp->v_writecount--; 4445 goto bad; 4446 } 4447 /* An extra reference on `nfp' has been held for us by falloc(). */ 4448 fp = nfp; 4449 nfp->f_vnode = vp; 4450 finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops); 4451 if (fmode & (O_EXLOCK | O_SHLOCK)) { 4452 lf.l_whence = SEEK_SET; 4453 lf.l_start = 0; 4454 lf.l_len = 0; 4455 if (fmode & O_EXLOCK) 4456 lf.l_type = F_WRLCK; 4457 else 4458 lf.l_type = F_RDLCK; 4459 type = F_FLOCK; 4460 if ((fmode & FNONBLOCK) == 0) 4461 type |= F_WAIT; 4462 VOP_UNLOCK(vp, 0); 4463 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 4464 type)) != 0) { 4465 /* 4466 * The lock request failed. Normally close the 4467 * descriptor but handle the case where someone might 4468 * have dup()d or close()d it when we weren't looking. 4469 */ 4470 fdclose(fdp, fp, indx, td); 4471 4472 /* 4473 * release our private reference 4474 */ 4475 fdrop(fp, td); 4476 goto out; 4477 } 4478 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4479 atomic_set_int(&fp->f_flag, FHASLOCK); 4480 } 4481 4482 VOP_UNLOCK(vp, 0); 4483 fdrop(fp, td); 4484 vfs_rel(mp); 4485 VFS_UNLOCK_GIANT(vfslocked); 4486 td->td_retval[0] = indx; 4487 return (0); 4488 4489 bad: 4490 vput(vp); 4491 out: 4492 vfs_rel(mp); 4493 VFS_UNLOCK_GIANT(vfslocked); 4494 return (error); 4495 } 4496 4497 /* 4498 * Stat an (NFS) file handle. 4499 */ 4500 #ifndef _SYS_SYSPROTO_H_ 4501 struct fhstat_args { 4502 struct fhandle *u_fhp; 4503 struct stat *sb; 4504 }; 4505 #endif 4506 int 4507 fhstat(td, uap) 4508 struct thread *td; 4509 register struct fhstat_args /* { 4510 struct fhandle *u_fhp; 4511 struct stat *sb; 4512 } */ *uap; 4513 { 4514 struct stat sb; 4515 fhandle_t fh; 4516 struct mount *mp; 4517 struct vnode *vp; 4518 int vfslocked; 4519 int error; 4520 4521 error = priv_check(td, PRIV_VFS_FHSTAT); 4522 if (error) 4523 return (error); 4524 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4525 if (error) 4526 return (error); 4527 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 4528 return (ESTALE); 4529 vfslocked = VFS_LOCK_GIANT(mp); 4530 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) { 4531 vfs_rel(mp); 4532 VFS_UNLOCK_GIANT(vfslocked); 4533 return (error); 4534 } 4535 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 4536 vput(vp); 4537 vfs_rel(mp); 4538 VFS_UNLOCK_GIANT(vfslocked); 4539 if (error) 4540 return (error); 4541 error = copyout(&sb, uap->sb, sizeof(sb)); 4542 return (error); 4543 } 4544 4545 /* 4546 * Implement fstatfs() for (NFS) file handles. 4547 */ 4548 #ifndef _SYS_SYSPROTO_H_ 4549 struct fhstatfs_args { 4550 struct fhandle *u_fhp; 4551 struct statfs *buf; 4552 }; 4553 #endif 4554 int 4555 fhstatfs(td, uap) 4556 struct thread *td; 4557 struct fhstatfs_args /* { 4558 struct fhandle *u_fhp; 4559 struct statfs *buf; 4560 } */ *uap; 4561 { 4562 struct statfs sf; 4563 fhandle_t fh; 4564 int error; 4565 4566 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4567 if (error) 4568 return (error); 4569 error = kern_fhstatfs(td, fh, &sf); 4570 if (error) 4571 return (error); 4572 return (copyout(&sf, uap->buf, sizeof(sf))); 4573 } 4574 4575 int 4576 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) 4577 { 4578 struct statfs *sp; 4579 struct mount *mp; 4580 struct vnode *vp; 4581 int vfslocked; 4582 int error; 4583 4584 error = priv_check(td, PRIV_VFS_FHSTATFS); 4585 if (error) 4586 return (error); 4587 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 4588 return (ESTALE); 4589 vfslocked = VFS_LOCK_GIANT(mp); 4590 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); 4591 if (error) { 4592 VFS_UNLOCK_GIANT(vfslocked); 4593 vfs_rel(mp); 4594 return (error); 4595 } 4596 vput(vp); 4597 error = prison_canseemount(td->td_ucred, mp); 4598 if (error) 4599 goto out; 4600 #ifdef MAC 4601 error = mac_mount_check_stat(td->td_ucred, mp); 4602 if (error) 4603 goto out; 4604 #endif 4605 /* 4606 * Set these in case the underlying filesystem fails to do so. 4607 */ 4608 sp = &mp->mnt_stat; 4609 sp->f_version = STATFS_VERSION; 4610 sp->f_namemax = NAME_MAX; 4611 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 4612 error = VFS_STATFS(mp, sp, td); 4613 if (error == 0) 4614 *buf = *sp; 4615 out: 4616 vfs_rel(mp); 4617 VFS_UNLOCK_GIANT(vfslocked); 4618 return (error); 4619 } 4620