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