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