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