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