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