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 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 1165 VATTR_NULL(&vat); 1166 vat.va_size = 0; 1167 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1168 #ifdef MAC 1169 error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); 1170 if (error == 0) 1171 #endif 1172 error = VOP_SETATTR(vp, &vat, td->td_ucred); 1173 VOP_UNLOCK(vp, 0); 1174 vn_finished_write(mp); 1175 if (error) 1176 goto bad; 1177 } 1178 VFS_UNLOCK_GIANT(vfslocked); 1179 /* 1180 * Release our private reference, leaving the one associated with 1181 * the descriptor table intact. 1182 */ 1183 fdrop(fp, td); 1184 td->td_retval[0] = indx; 1185 return (0); 1186 bad: 1187 VFS_UNLOCK_GIANT(vfslocked); 1188 fdclose(fdp, fp, indx, td); 1189 fdrop(fp, td); 1190 return (error); 1191 } 1192 1193 #ifdef COMPAT_43 1194 /* 1195 * Create a file. 1196 */ 1197 #ifndef _SYS_SYSPROTO_H_ 1198 struct ocreat_args { 1199 char *path; 1200 int mode; 1201 }; 1202 #endif 1203 int 1204 ocreat(td, uap) 1205 struct thread *td; 1206 register struct ocreat_args /* { 1207 char *path; 1208 int mode; 1209 } */ *uap; 1210 { 1211 1212 return (kern_open(td, uap->path, UIO_USERSPACE, 1213 O_WRONLY | O_CREAT | O_TRUNC, uap->mode)); 1214 } 1215 #endif /* COMPAT_43 */ 1216 1217 /* 1218 * Create a special file. 1219 */ 1220 #ifndef _SYS_SYSPROTO_H_ 1221 struct mknod_args { 1222 char *path; 1223 int mode; 1224 int dev; 1225 }; 1226 #endif 1227 int 1228 mknod(td, uap) 1229 struct thread *td; 1230 register struct mknod_args /* { 1231 char *path; 1232 int mode; 1233 int dev; 1234 } */ *uap; 1235 { 1236 1237 return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); 1238 } 1239 1240 #ifndef _SYS_SYSPROTO_H_ 1241 struct mknodat_args { 1242 int fd; 1243 char *path; 1244 mode_t mode; 1245 dev_t dev; 1246 }; 1247 #endif 1248 int 1249 mknodat(struct thread *td, struct mknodat_args *uap) 1250 { 1251 1252 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, 1253 uap->dev)); 1254 } 1255 1256 int 1257 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, 1258 int dev) 1259 { 1260 1261 return (kern_mknodat(td, AT_FDCWD, path, pathseg, mode, dev)); 1262 } 1263 1264 int 1265 kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1266 int mode, int dev) 1267 { 1268 struct vnode *vp; 1269 struct mount *mp; 1270 struct vattr vattr; 1271 int error; 1272 int whiteout = 0; 1273 struct nameidata nd; 1274 int vfslocked; 1275 1276 AUDIT_ARG(mode, mode); 1277 AUDIT_ARG(dev, dev); 1278 switch (mode & S_IFMT) { 1279 case S_IFCHR: 1280 case S_IFBLK: 1281 error = priv_check(td, PRIV_VFS_MKNOD_DEV); 1282 break; 1283 case S_IFMT: 1284 error = priv_check(td, PRIV_VFS_MKNOD_BAD); 1285 break; 1286 case S_IFWHT: 1287 error = priv_check(td, PRIV_VFS_MKNOD_WHT); 1288 break; 1289 case S_IFIFO: 1290 if (dev == 0) 1291 return (kern_mkfifoat(td, fd, path, pathseg, mode)); 1292 /* FALLTHROUGH */ 1293 default: 1294 error = EINVAL; 1295 break; 1296 } 1297 if (error) 1298 return (error); 1299 restart: 1300 bwillwrite(); 1301 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1302 pathseg, path, fd, td); 1303 if ((error = namei(&nd)) != 0) 1304 return (error); 1305 vfslocked = NDHASGIANT(&nd); 1306 vp = nd.ni_vp; 1307 if (vp != NULL) { 1308 NDFREE(&nd, NDF_ONLY_PNBUF); 1309 if (vp == nd.ni_dvp) 1310 vrele(nd.ni_dvp); 1311 else 1312 vput(nd.ni_dvp); 1313 vrele(vp); 1314 VFS_UNLOCK_GIANT(vfslocked); 1315 return (EEXIST); 1316 } else { 1317 VATTR_NULL(&vattr); 1318 FILEDESC_SLOCK(td->td_proc->p_fd); 1319 vattr.va_mode = (mode & ALLPERMS) & 1320 ~td->td_proc->p_fd->fd_cmask; 1321 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1322 vattr.va_rdev = dev; 1323 whiteout = 0; 1324 1325 switch (mode & S_IFMT) { 1326 case S_IFMT: /* used by badsect to flag bad sectors */ 1327 vattr.va_type = VBAD; 1328 break; 1329 case S_IFCHR: 1330 vattr.va_type = VCHR; 1331 break; 1332 case S_IFBLK: 1333 vattr.va_type = VBLK; 1334 break; 1335 case S_IFWHT: 1336 whiteout = 1; 1337 break; 1338 default: 1339 panic("kern_mknod: invalid mode"); 1340 } 1341 } 1342 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1343 NDFREE(&nd, NDF_ONLY_PNBUF); 1344 vput(nd.ni_dvp); 1345 VFS_UNLOCK_GIANT(vfslocked); 1346 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1347 return (error); 1348 goto restart; 1349 } 1350 #ifdef MAC 1351 if (error == 0 && !whiteout) 1352 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, 1353 &nd.ni_cnd, &vattr); 1354 #endif 1355 if (!error) { 1356 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1357 if (whiteout) 1358 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1359 else { 1360 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1361 &nd.ni_cnd, &vattr); 1362 if (error == 0) 1363 vput(nd.ni_vp); 1364 } 1365 } 1366 NDFREE(&nd, NDF_ONLY_PNBUF); 1367 vput(nd.ni_dvp); 1368 vn_finished_write(mp); 1369 VFS_UNLOCK_GIANT(vfslocked); 1370 return (error); 1371 } 1372 1373 /* 1374 * Create a named pipe. 1375 */ 1376 #ifndef _SYS_SYSPROTO_H_ 1377 struct mkfifo_args { 1378 char *path; 1379 int mode; 1380 }; 1381 #endif 1382 int 1383 mkfifo(td, uap) 1384 struct thread *td; 1385 register struct mkfifo_args /* { 1386 char *path; 1387 int mode; 1388 } */ *uap; 1389 { 1390 1391 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); 1392 } 1393 1394 #ifndef _SYS_SYSPROTO_H_ 1395 struct mkfifoat_args { 1396 int fd; 1397 char *path; 1398 mode_t mode; 1399 }; 1400 #endif 1401 int 1402 mkfifoat(struct thread *td, struct mkfifoat_args *uap) 1403 { 1404 1405 return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE, 1406 uap->mode)); 1407 } 1408 1409 int 1410 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) 1411 { 1412 1413 return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode)); 1414 } 1415 1416 int 1417 kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1418 int mode) 1419 { 1420 struct mount *mp; 1421 struct vattr vattr; 1422 int error; 1423 struct nameidata nd; 1424 int vfslocked; 1425 1426 AUDIT_ARG(mode, mode); 1427 restart: 1428 bwillwrite(); 1429 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1430 pathseg, path, fd, td); 1431 if ((error = namei(&nd)) != 0) 1432 return (error); 1433 vfslocked = NDHASGIANT(&nd); 1434 if (nd.ni_vp != NULL) { 1435 NDFREE(&nd, NDF_ONLY_PNBUF); 1436 if (nd.ni_vp == nd.ni_dvp) 1437 vrele(nd.ni_dvp); 1438 else 1439 vput(nd.ni_dvp); 1440 vrele(nd.ni_vp); 1441 VFS_UNLOCK_GIANT(vfslocked); 1442 return (EEXIST); 1443 } 1444 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1445 NDFREE(&nd, NDF_ONLY_PNBUF); 1446 vput(nd.ni_dvp); 1447 VFS_UNLOCK_GIANT(vfslocked); 1448 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1449 return (error); 1450 goto restart; 1451 } 1452 VATTR_NULL(&vattr); 1453 vattr.va_type = VFIFO; 1454 FILEDESC_SLOCK(td->td_proc->p_fd); 1455 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; 1456 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1457 #ifdef MAC 1458 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1459 &vattr); 1460 if (error) 1461 goto out; 1462 #endif 1463 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1464 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1465 if (error == 0) 1466 vput(nd.ni_vp); 1467 #ifdef MAC 1468 out: 1469 #endif 1470 vput(nd.ni_dvp); 1471 vn_finished_write(mp); 1472 VFS_UNLOCK_GIANT(vfslocked); 1473 NDFREE(&nd, NDF_ONLY_PNBUF); 1474 return (error); 1475 } 1476 1477 /* 1478 * Make a hard file link. 1479 */ 1480 #ifndef _SYS_SYSPROTO_H_ 1481 struct link_args { 1482 char *path; 1483 char *link; 1484 }; 1485 #endif 1486 int 1487 link(td, uap) 1488 struct thread *td; 1489 register struct link_args /* { 1490 char *path; 1491 char *link; 1492 } */ *uap; 1493 { 1494 1495 return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); 1496 } 1497 1498 #ifndef _SYS_SYSPROTO_H_ 1499 struct linkat_args { 1500 int fd1; 1501 char *path1; 1502 int fd2; 1503 char *path2; 1504 int flag; 1505 }; 1506 #endif 1507 int 1508 linkat(struct thread *td, struct linkat_args *uap) 1509 { 1510 int flag; 1511 1512 flag = uap->flag; 1513 if (flag & ~AT_SYMLINK_FOLLOW) 1514 return (EINVAL); 1515 1516 return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, 1517 UIO_USERSPACE, (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW)); 1518 } 1519 1520 static int hardlink_check_uid = 0; 1521 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, 1522 &hardlink_check_uid, 0, 1523 "Unprivileged processes cannot create hard links to files owned by other " 1524 "users"); 1525 static int hardlink_check_gid = 0; 1526 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, 1527 &hardlink_check_gid, 0, 1528 "Unprivileged processes cannot create hard links to files owned by other " 1529 "groups"); 1530 1531 static int 1532 can_hardlink(struct vnode *vp, struct ucred *cred) 1533 { 1534 struct vattr va; 1535 int error; 1536 1537 if (!hardlink_check_uid && !hardlink_check_gid) 1538 return (0); 1539 1540 error = VOP_GETATTR(vp, &va, cred); 1541 if (error != 0) 1542 return (error); 1543 1544 if (hardlink_check_uid && cred->cr_uid != va.va_uid) { 1545 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1546 if (error) 1547 return (error); 1548 } 1549 1550 if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { 1551 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1552 if (error) 1553 return (error); 1554 } 1555 1556 return (0); 1557 } 1558 1559 int 1560 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) 1561 { 1562 1563 return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW)); 1564 } 1565 1566 int 1567 kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, 1568 enum uio_seg segflg, int follow) 1569 { 1570 struct vnode *vp; 1571 struct mount *mp; 1572 struct nameidata nd; 1573 int vfslocked; 1574 int lvfslocked; 1575 int error; 1576 1577 bwillwrite(); 1578 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, segflg, path1, 1579 fd1, td); 1580 1581 if ((error = namei(&nd)) != 0) 1582 return (error); 1583 vfslocked = NDHASGIANT(&nd); 1584 NDFREE(&nd, NDF_ONLY_PNBUF); 1585 vp = nd.ni_vp; 1586 if (vp->v_type == VDIR) { 1587 vrele(vp); 1588 VFS_UNLOCK_GIANT(vfslocked); 1589 return (EPERM); /* POSIX */ 1590 } 1591 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 1592 vrele(vp); 1593 VFS_UNLOCK_GIANT(vfslocked); 1594 return (error); 1595 } 1596 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1597 segflg, path2, fd2, td); 1598 if ((error = namei(&nd)) == 0) { 1599 lvfslocked = NDHASGIANT(&nd); 1600 if (nd.ni_vp != NULL) { 1601 if (nd.ni_dvp == nd.ni_vp) 1602 vrele(nd.ni_dvp); 1603 else 1604 vput(nd.ni_dvp); 1605 vrele(nd.ni_vp); 1606 error = EEXIST; 1607 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) 1608 == 0) { 1609 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1610 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 1611 error = can_hardlink(vp, td->td_ucred); 1612 if (error == 0) 1613 #ifdef MAC 1614 error = mac_vnode_check_link(td->td_ucred, 1615 nd.ni_dvp, vp, &nd.ni_cnd); 1616 if (error == 0) 1617 #endif 1618 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1619 VOP_UNLOCK(vp, 0); 1620 vput(nd.ni_dvp); 1621 } 1622 NDFREE(&nd, NDF_ONLY_PNBUF); 1623 VFS_UNLOCK_GIANT(lvfslocked); 1624 } 1625 vrele(vp); 1626 vn_finished_write(mp); 1627 VFS_UNLOCK_GIANT(vfslocked); 1628 return (error); 1629 } 1630 1631 /* 1632 * Make a symbolic link. 1633 */ 1634 #ifndef _SYS_SYSPROTO_H_ 1635 struct symlink_args { 1636 char *path; 1637 char *link; 1638 }; 1639 #endif 1640 int 1641 symlink(td, uap) 1642 struct thread *td; 1643 register struct symlink_args /* { 1644 char *path; 1645 char *link; 1646 } */ *uap; 1647 { 1648 1649 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); 1650 } 1651 1652 #ifndef _SYS_SYSPROTO_H_ 1653 struct symlinkat_args { 1654 char *path; 1655 int fd; 1656 char *path2; 1657 }; 1658 #endif 1659 int 1660 symlinkat(struct thread *td, struct symlinkat_args *uap) 1661 { 1662 1663 return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2, 1664 UIO_USERSPACE)); 1665 } 1666 1667 int 1668 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) 1669 { 1670 1671 return (kern_symlinkat(td, path, AT_FDCWD, link, segflg)); 1672 } 1673 1674 int 1675 kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, 1676 enum uio_seg segflg) 1677 { 1678 struct mount *mp; 1679 struct vattr vattr; 1680 char *syspath; 1681 int error; 1682 struct nameidata nd; 1683 int vfslocked; 1684 1685 if (segflg == UIO_SYSSPACE) { 1686 syspath = path1; 1687 } else { 1688 syspath = uma_zalloc(namei_zone, M_WAITOK); 1689 if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0) 1690 goto out; 1691 } 1692 AUDIT_ARG(text, syspath); 1693 restart: 1694 bwillwrite(); 1695 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 1696 segflg, path2, fd, td); 1697 if ((error = namei(&nd)) != 0) 1698 goto out; 1699 vfslocked = NDHASGIANT(&nd); 1700 if (nd.ni_vp) { 1701 NDFREE(&nd, NDF_ONLY_PNBUF); 1702 if (nd.ni_vp == nd.ni_dvp) 1703 vrele(nd.ni_dvp); 1704 else 1705 vput(nd.ni_dvp); 1706 vrele(nd.ni_vp); 1707 VFS_UNLOCK_GIANT(vfslocked); 1708 error = EEXIST; 1709 goto out; 1710 } 1711 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1712 NDFREE(&nd, NDF_ONLY_PNBUF); 1713 vput(nd.ni_dvp); 1714 VFS_UNLOCK_GIANT(vfslocked); 1715 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1716 goto out; 1717 goto restart; 1718 } 1719 VATTR_NULL(&vattr); 1720 FILEDESC_SLOCK(td->td_proc->p_fd); 1721 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; 1722 FILEDESC_SUNLOCK(td->td_proc->p_fd); 1723 #ifdef MAC 1724 vattr.va_type = VLNK; 1725 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1726 &vattr); 1727 if (error) 1728 goto out2; 1729 #endif 1730 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1731 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); 1732 if (error == 0) 1733 vput(nd.ni_vp); 1734 #ifdef MAC 1735 out2: 1736 #endif 1737 NDFREE(&nd, NDF_ONLY_PNBUF); 1738 vput(nd.ni_dvp); 1739 vn_finished_write(mp); 1740 VFS_UNLOCK_GIANT(vfslocked); 1741 out: 1742 if (segflg != UIO_SYSSPACE) 1743 uma_zfree(namei_zone, syspath); 1744 return (error); 1745 } 1746 1747 /* 1748 * Delete a whiteout from the filesystem. 1749 */ 1750 int 1751 undelete(td, uap) 1752 struct thread *td; 1753 register struct undelete_args /* { 1754 char *path; 1755 } */ *uap; 1756 { 1757 int error; 1758 struct mount *mp; 1759 struct nameidata nd; 1760 int vfslocked; 1761 1762 restart: 1763 bwillwrite(); 1764 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1, 1765 UIO_USERSPACE, uap->path, td); 1766 error = namei(&nd); 1767 if (error) 1768 return (error); 1769 vfslocked = NDHASGIANT(&nd); 1770 1771 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1772 NDFREE(&nd, NDF_ONLY_PNBUF); 1773 if (nd.ni_vp == nd.ni_dvp) 1774 vrele(nd.ni_dvp); 1775 else 1776 vput(nd.ni_dvp); 1777 if (nd.ni_vp) 1778 vrele(nd.ni_vp); 1779 VFS_UNLOCK_GIANT(vfslocked); 1780 return (EEXIST); 1781 } 1782 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1783 NDFREE(&nd, NDF_ONLY_PNBUF); 1784 vput(nd.ni_dvp); 1785 VFS_UNLOCK_GIANT(vfslocked); 1786 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1787 return (error); 1788 goto restart; 1789 } 1790 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1791 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); 1792 NDFREE(&nd, NDF_ONLY_PNBUF); 1793 vput(nd.ni_dvp); 1794 vn_finished_write(mp); 1795 VFS_UNLOCK_GIANT(vfslocked); 1796 return (error); 1797 } 1798 1799 /* 1800 * Delete a name from the filesystem. 1801 */ 1802 #ifndef _SYS_SYSPROTO_H_ 1803 struct unlink_args { 1804 char *path; 1805 }; 1806 #endif 1807 int 1808 unlink(td, uap) 1809 struct thread *td; 1810 struct unlink_args /* { 1811 char *path; 1812 } */ *uap; 1813 { 1814 1815 return (kern_unlink(td, uap->path, UIO_USERSPACE)); 1816 } 1817 1818 #ifndef _SYS_SYSPROTO_H_ 1819 struct unlinkat_args { 1820 int fd; 1821 char *path; 1822 int flag; 1823 }; 1824 #endif 1825 int 1826 unlinkat(struct thread *td, struct unlinkat_args *uap) 1827 { 1828 int flag = uap->flag; 1829 int fd = uap->fd; 1830 char *path = uap->path; 1831 1832 if (flag & ~AT_REMOVEDIR) 1833 return (EINVAL); 1834 1835 if (flag & AT_REMOVEDIR) 1836 return (kern_rmdirat(td, fd, path, UIO_USERSPACE)); 1837 else 1838 return (kern_unlinkat(td, fd, path, UIO_USERSPACE)); 1839 } 1840 1841 int 1842 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) 1843 { 1844 1845 return (kern_unlinkat(td, AT_FDCWD, path, pathseg)); 1846 } 1847 1848 int 1849 kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 1850 { 1851 struct mount *mp; 1852 struct vnode *vp; 1853 int error; 1854 struct nameidata nd; 1855 int vfslocked; 1856 1857 restart: 1858 bwillwrite(); 1859 NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, 1860 pathseg, path, fd, td); 1861 if ((error = namei(&nd)) != 0) 1862 return (error == EINVAL ? EPERM : error); 1863 vfslocked = NDHASGIANT(&nd); 1864 vp = nd.ni_vp; 1865 if (vp->v_type == VDIR) 1866 error = EPERM; /* POSIX */ 1867 else { 1868 /* 1869 * The root of a mounted filesystem cannot be deleted. 1870 * 1871 * XXX: can this only be a VDIR case? 1872 */ 1873 if (vp->v_vflag & VV_ROOT) 1874 error = EBUSY; 1875 } 1876 if (error == 0) { 1877 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1878 NDFREE(&nd, NDF_ONLY_PNBUF); 1879 vput(nd.ni_dvp); 1880 if (vp == nd.ni_dvp) 1881 vrele(vp); 1882 else 1883 vput(vp); 1884 VFS_UNLOCK_GIANT(vfslocked); 1885 if ((error = vn_start_write(NULL, &mp, 1886 V_XSLEEP | PCATCH)) != 0) 1887 return (error); 1888 goto restart; 1889 } 1890 #ifdef MAC 1891 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 1892 &nd.ni_cnd); 1893 if (error) 1894 goto out; 1895 #endif 1896 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 1897 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1898 #ifdef MAC 1899 out: 1900 #endif 1901 vn_finished_write(mp); 1902 } 1903 NDFREE(&nd, NDF_ONLY_PNBUF); 1904 vput(nd.ni_dvp); 1905 if (vp == nd.ni_dvp) 1906 vrele(vp); 1907 else 1908 vput(vp); 1909 VFS_UNLOCK_GIANT(vfslocked); 1910 return (error); 1911 } 1912 1913 /* 1914 * Reposition read/write file offset. 1915 */ 1916 #ifndef _SYS_SYSPROTO_H_ 1917 struct lseek_args { 1918 int fd; 1919 int pad; 1920 off_t offset; 1921 int whence; 1922 }; 1923 #endif 1924 int 1925 lseek(td, uap) 1926 struct thread *td; 1927 register struct lseek_args /* { 1928 int fd; 1929 int pad; 1930 off_t offset; 1931 int whence; 1932 } */ *uap; 1933 { 1934 struct ucred *cred = td->td_ucred; 1935 struct file *fp; 1936 struct vnode *vp; 1937 struct vattr vattr; 1938 off_t offset; 1939 int error, noneg; 1940 int vfslocked; 1941 1942 if ((error = fget(td, uap->fd, &fp)) != 0) 1943 return (error); 1944 if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { 1945 fdrop(fp, td); 1946 return (ESPIPE); 1947 } 1948 vp = fp->f_vnode; 1949 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 1950 noneg = (vp->v_type != VCHR); 1951 offset = uap->offset; 1952 switch (uap->whence) { 1953 case L_INCR: 1954 if (noneg && 1955 (fp->f_offset < 0 || 1956 (offset > 0 && fp->f_offset > OFF_MAX - offset))) { 1957 error = EOVERFLOW; 1958 break; 1959 } 1960 offset += fp->f_offset; 1961 break; 1962 case L_XTND: 1963 vn_lock(vp, LK_SHARED | LK_RETRY); 1964 error = VOP_GETATTR(vp, &vattr, cred); 1965 VOP_UNLOCK(vp, 0); 1966 if (error) 1967 break; 1968 if (noneg && 1969 (vattr.va_size > OFF_MAX || 1970 (offset > 0 && vattr.va_size > OFF_MAX - offset))) { 1971 error = EOVERFLOW; 1972 break; 1973 } 1974 offset += vattr.va_size; 1975 break; 1976 case L_SET: 1977 break; 1978 case SEEK_DATA: 1979 error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td); 1980 break; 1981 case SEEK_HOLE: 1982 error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td); 1983 break; 1984 default: 1985 error = EINVAL; 1986 } 1987 if (error == 0 && noneg && offset < 0) 1988 error = EINVAL; 1989 if (error != 0) 1990 goto drop; 1991 fp->f_offset = offset; 1992 *(off_t *)(td->td_retval) = fp->f_offset; 1993 drop: 1994 fdrop(fp, td); 1995 VFS_UNLOCK_GIANT(vfslocked); 1996 return (error); 1997 } 1998 1999 #if defined(COMPAT_43) 2000 /* 2001 * Reposition read/write file offset. 2002 */ 2003 #ifndef _SYS_SYSPROTO_H_ 2004 struct olseek_args { 2005 int fd; 2006 long offset; 2007 int whence; 2008 }; 2009 #endif 2010 int 2011 olseek(td, uap) 2012 struct thread *td; 2013 register struct olseek_args /* { 2014 int fd; 2015 long offset; 2016 int whence; 2017 } */ *uap; 2018 { 2019 struct lseek_args /* { 2020 int fd; 2021 int pad; 2022 off_t offset; 2023 int whence; 2024 } */ nuap; 2025 2026 nuap.fd = uap->fd; 2027 nuap.offset = uap->offset; 2028 nuap.whence = uap->whence; 2029 return (lseek(td, &nuap)); 2030 } 2031 #endif /* COMPAT_43 */ 2032 2033 /* Version with the 'pad' argument */ 2034 int 2035 freebsd6_lseek(td, uap) 2036 struct thread *td; 2037 register struct freebsd6_lseek_args *uap; 2038 { 2039 struct lseek_args ouap; 2040 2041 ouap.fd = uap->fd; 2042 ouap.offset = uap->offset; 2043 ouap.whence = uap->whence; 2044 return (lseek(td, &ouap)); 2045 } 2046 2047 /* 2048 * Check access permissions using passed credentials. 2049 */ 2050 static int 2051 vn_access(vp, user_flags, cred, td) 2052 struct vnode *vp; 2053 int user_flags; 2054 struct ucred *cred; 2055 struct thread *td; 2056 { 2057 int error; 2058 accmode_t accmode; 2059 2060 /* Flags == 0 means only check for existence. */ 2061 error = 0; 2062 if (user_flags) { 2063 accmode = 0; 2064 if (user_flags & R_OK) 2065 accmode |= VREAD; 2066 if (user_flags & W_OK) 2067 accmode |= VWRITE; 2068 if (user_flags & X_OK) 2069 accmode |= VEXEC; 2070 #ifdef MAC 2071 error = mac_vnode_check_access(cred, vp, accmode); 2072 if (error) 2073 return (error); 2074 #endif 2075 if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 2076 error = VOP_ACCESS(vp, accmode, cred, td); 2077 } 2078 return (error); 2079 } 2080 2081 /* 2082 * Check access permissions using "real" credentials. 2083 */ 2084 #ifndef _SYS_SYSPROTO_H_ 2085 struct access_args { 2086 char *path; 2087 int flags; 2088 }; 2089 #endif 2090 int 2091 access(td, uap) 2092 struct thread *td; 2093 register struct access_args /* { 2094 char *path; 2095 int flags; 2096 } */ *uap; 2097 { 2098 2099 return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags)); 2100 } 2101 2102 #ifndef _SYS_SYSPROTO_H_ 2103 struct faccessat_args { 2104 int dirfd; 2105 char *path; 2106 int mode; 2107 int flag; 2108 } 2109 #endif 2110 int 2111 faccessat(struct thread *td, struct faccessat_args *uap) 2112 { 2113 2114 if (uap->flag & ~AT_EACCESS) 2115 return (EINVAL); 2116 return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, 2117 uap->mode)); 2118 } 2119 2120 int 2121 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2122 { 2123 2124 return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, mode)); 2125 } 2126 2127 int 2128 kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2129 int flags, int mode) 2130 { 2131 struct ucred *cred, *tmpcred; 2132 struct vnode *vp; 2133 struct nameidata nd; 2134 int vfslocked; 2135 int error; 2136 2137 /* 2138 * Create and modify a temporary credential instead of one that 2139 * is potentially shared. This could also mess up socket 2140 * buffer accounting which can run in an interrupt context. 2141 */ 2142 if (!(flags & AT_EACCESS)) { 2143 cred = td->td_ucred; 2144 tmpcred = crdup(cred); 2145 tmpcred->cr_uid = cred->cr_ruid; 2146 tmpcred->cr_groups[0] = cred->cr_rgid; 2147 td->td_ucred = tmpcred; 2148 } else 2149 cred = tmpcred = td->td_ucred; 2150 NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | 2151 AUDITVNODE1, pathseg, path, fd, td); 2152 if ((error = namei(&nd)) != 0) 2153 goto out1; 2154 vfslocked = NDHASGIANT(&nd); 2155 vp = nd.ni_vp; 2156 2157 error = vn_access(vp, mode, tmpcred, td); 2158 NDFREE(&nd, NDF_ONLY_PNBUF); 2159 vput(vp); 2160 VFS_UNLOCK_GIANT(vfslocked); 2161 out1: 2162 if (!(flags & AT_EACCESS)) { 2163 td->td_ucred = cred; 2164 crfree(tmpcred); 2165 } 2166 return (error); 2167 } 2168 2169 /* 2170 * Check access permissions using "effective" credentials. 2171 */ 2172 #ifndef _SYS_SYSPROTO_H_ 2173 struct eaccess_args { 2174 char *path; 2175 int flags; 2176 }; 2177 #endif 2178 int 2179 eaccess(td, uap) 2180 struct thread *td; 2181 register struct eaccess_args /* { 2182 char *path; 2183 int flags; 2184 } */ *uap; 2185 { 2186 2187 return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags)); 2188 } 2189 2190 int 2191 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags) 2192 { 2193 2194 return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, flags)); 2195 } 2196 2197 #if defined(COMPAT_43) 2198 /* 2199 * Get file status; this version follows links. 2200 */ 2201 #ifndef _SYS_SYSPROTO_H_ 2202 struct ostat_args { 2203 char *path; 2204 struct ostat *ub; 2205 }; 2206 #endif 2207 int 2208 ostat(td, uap) 2209 struct thread *td; 2210 register struct ostat_args /* { 2211 char *path; 2212 struct ostat *ub; 2213 } */ *uap; 2214 { 2215 struct stat sb; 2216 struct ostat osb; 2217 int error; 2218 2219 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2220 if (error) 2221 return (error); 2222 cvtstat(&sb, &osb); 2223 error = copyout(&osb, uap->ub, sizeof (osb)); 2224 return (error); 2225 } 2226 2227 /* 2228 * Get file status; this version does not follow links. 2229 */ 2230 #ifndef _SYS_SYSPROTO_H_ 2231 struct olstat_args { 2232 char *path; 2233 struct ostat *ub; 2234 }; 2235 #endif 2236 int 2237 olstat(td, uap) 2238 struct thread *td; 2239 register struct olstat_args /* { 2240 char *path; 2241 struct ostat *ub; 2242 } */ *uap; 2243 { 2244 struct stat sb; 2245 struct ostat osb; 2246 int error; 2247 2248 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2249 if (error) 2250 return (error); 2251 cvtstat(&sb, &osb); 2252 error = copyout(&osb, uap->ub, sizeof (osb)); 2253 return (error); 2254 } 2255 2256 /* 2257 * Convert from an old to a new stat structure. 2258 */ 2259 void 2260 cvtstat(st, ost) 2261 struct stat *st; 2262 struct ostat *ost; 2263 { 2264 2265 ost->st_dev = st->st_dev; 2266 ost->st_ino = st->st_ino; 2267 ost->st_mode = st->st_mode; 2268 ost->st_nlink = st->st_nlink; 2269 ost->st_uid = st->st_uid; 2270 ost->st_gid = st->st_gid; 2271 ost->st_rdev = st->st_rdev; 2272 if (st->st_size < (quad_t)1 << 32) 2273 ost->st_size = st->st_size; 2274 else 2275 ost->st_size = -2; 2276 ost->st_atime = st->st_atime; 2277 ost->st_mtime = st->st_mtime; 2278 ost->st_ctime = st->st_ctime; 2279 ost->st_blksize = st->st_blksize; 2280 ost->st_blocks = st->st_blocks; 2281 ost->st_flags = st->st_flags; 2282 ost->st_gen = st->st_gen; 2283 } 2284 #endif /* COMPAT_43 */ 2285 2286 /* 2287 * Get file status; this version follows links. 2288 */ 2289 #ifndef _SYS_SYSPROTO_H_ 2290 struct stat_args { 2291 char *path; 2292 struct stat *ub; 2293 }; 2294 #endif 2295 int 2296 stat(td, uap) 2297 struct thread *td; 2298 register struct stat_args /* { 2299 char *path; 2300 struct stat *ub; 2301 } */ *uap; 2302 { 2303 struct stat sb; 2304 int error; 2305 2306 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2307 if (error == 0) 2308 error = copyout(&sb, uap->ub, sizeof (sb)); 2309 return (error); 2310 } 2311 2312 #ifndef _SYS_SYSPROTO_H_ 2313 struct fstatat_args { 2314 int fd; 2315 char *path; 2316 struct stat *buf; 2317 int flag; 2318 } 2319 #endif 2320 int 2321 fstatat(struct thread *td, struct fstatat_args *uap) 2322 { 2323 struct stat sb; 2324 int error; 2325 2326 error = kern_statat(td, uap->flag, uap->fd, uap->path, 2327 UIO_USERSPACE, &sb); 2328 if (error == 0) 2329 error = copyout(&sb, uap->buf, sizeof (sb)); 2330 return (error); 2331 } 2332 2333 int 2334 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2335 { 2336 2337 return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); 2338 } 2339 2340 int 2341 kern_statat(struct thread *td, int flag, int fd, char *path, 2342 enum uio_seg pathseg, struct stat *sbp) 2343 { 2344 2345 return (kern_statat_vnhook(td, flag, fd, path, pathseg, sbp, NULL)); 2346 } 2347 2348 int 2349 kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, 2350 enum uio_seg pathseg, struct stat *sbp, 2351 void (*hook)(struct vnode *vp, struct stat *sbp)) 2352 { 2353 struct nameidata nd; 2354 struct stat sb; 2355 int error, vfslocked; 2356 2357 if (flag & ~AT_SYMLINK_NOFOLLOW) 2358 return (EINVAL); 2359 2360 NDINIT_AT(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : 2361 FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, 2362 path, fd, td); 2363 2364 if ((error = namei(&nd)) != 0) 2365 return (error); 2366 vfslocked = NDHASGIANT(&nd); 2367 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 2368 if (!error) { 2369 SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); 2370 if (S_ISREG(sb.st_mode)) 2371 SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); 2372 if (__predict_false(hook != NULL)) 2373 hook(nd.ni_vp, &sb); 2374 } 2375 NDFREE(&nd, NDF_ONLY_PNBUF); 2376 vput(nd.ni_vp); 2377 VFS_UNLOCK_GIANT(vfslocked); 2378 if (error) 2379 return (error); 2380 *sbp = sb; 2381 #ifdef KTRACE 2382 if (KTRPOINT(td, KTR_STRUCT)) 2383 ktrstat(&sb); 2384 #endif 2385 return (0); 2386 } 2387 2388 /* 2389 * Get file status; this version does not follow links. 2390 */ 2391 #ifndef _SYS_SYSPROTO_H_ 2392 struct lstat_args { 2393 char *path; 2394 struct stat *ub; 2395 }; 2396 #endif 2397 int 2398 lstat(td, uap) 2399 struct thread *td; 2400 register struct lstat_args /* { 2401 char *path; 2402 struct stat *ub; 2403 } */ *uap; 2404 { 2405 struct stat sb; 2406 int error; 2407 2408 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2409 if (error == 0) 2410 error = copyout(&sb, uap->ub, sizeof (sb)); 2411 return (error); 2412 } 2413 2414 int 2415 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2416 { 2417 2418 return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, 2419 sbp)); 2420 } 2421 2422 /* 2423 * Implementation of the NetBSD [l]stat() functions. 2424 */ 2425 void 2426 cvtnstat(sb, nsb) 2427 struct stat *sb; 2428 struct nstat *nsb; 2429 { 2430 bzero(nsb, sizeof *nsb); 2431 nsb->st_dev = sb->st_dev; 2432 nsb->st_ino = sb->st_ino; 2433 nsb->st_mode = sb->st_mode; 2434 nsb->st_nlink = sb->st_nlink; 2435 nsb->st_uid = sb->st_uid; 2436 nsb->st_gid = sb->st_gid; 2437 nsb->st_rdev = sb->st_rdev; 2438 nsb->st_atimespec = sb->st_atimespec; 2439 nsb->st_mtimespec = sb->st_mtimespec; 2440 nsb->st_ctimespec = sb->st_ctimespec; 2441 nsb->st_size = sb->st_size; 2442 nsb->st_blocks = sb->st_blocks; 2443 nsb->st_blksize = sb->st_blksize; 2444 nsb->st_flags = sb->st_flags; 2445 nsb->st_gen = sb->st_gen; 2446 nsb->st_birthtimespec = sb->st_birthtimespec; 2447 } 2448 2449 #ifndef _SYS_SYSPROTO_H_ 2450 struct nstat_args { 2451 char *path; 2452 struct nstat *ub; 2453 }; 2454 #endif 2455 int 2456 nstat(td, uap) 2457 struct thread *td; 2458 register struct nstat_args /* { 2459 char *path; 2460 struct nstat *ub; 2461 } */ *uap; 2462 { 2463 struct stat sb; 2464 struct nstat nsb; 2465 int error; 2466 2467 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2468 if (error) 2469 return (error); 2470 cvtnstat(&sb, &nsb); 2471 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2472 return (error); 2473 } 2474 2475 /* 2476 * NetBSD lstat. Get file status; this version does not follow links. 2477 */ 2478 #ifndef _SYS_SYSPROTO_H_ 2479 struct lstat_args { 2480 char *path; 2481 struct stat *ub; 2482 }; 2483 #endif 2484 int 2485 nlstat(td, uap) 2486 struct thread *td; 2487 register struct nlstat_args /* { 2488 char *path; 2489 struct nstat *ub; 2490 } */ *uap; 2491 { 2492 struct stat sb; 2493 struct nstat nsb; 2494 int error; 2495 2496 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2497 if (error) 2498 return (error); 2499 cvtnstat(&sb, &nsb); 2500 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2501 return (error); 2502 } 2503 2504 /* 2505 * Get configurable pathname variables. 2506 */ 2507 #ifndef _SYS_SYSPROTO_H_ 2508 struct pathconf_args { 2509 char *path; 2510 int name; 2511 }; 2512 #endif 2513 int 2514 pathconf(td, uap) 2515 struct thread *td; 2516 register struct pathconf_args /* { 2517 char *path; 2518 int name; 2519 } */ *uap; 2520 { 2521 2522 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name)); 2523 } 2524 2525 int 2526 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name) 2527 { 2528 struct nameidata nd; 2529 int error, vfslocked; 2530 2531 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | 2532 AUDITVNODE1, pathseg, path, td); 2533 if ((error = namei(&nd)) != 0) 2534 return (error); 2535 vfslocked = NDHASGIANT(&nd); 2536 NDFREE(&nd, NDF_ONLY_PNBUF); 2537 2538 /* If asynchronous I/O is available, it works for all files. */ 2539 if (name == _PC_ASYNC_IO) 2540 td->td_retval[0] = async_io_version; 2541 else 2542 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval); 2543 vput(nd.ni_vp); 2544 VFS_UNLOCK_GIANT(vfslocked); 2545 return (error); 2546 } 2547 2548 /* 2549 * Return target name of a symbolic link. 2550 */ 2551 #ifndef _SYS_SYSPROTO_H_ 2552 struct readlink_args { 2553 char *path; 2554 char *buf; 2555 size_t count; 2556 }; 2557 #endif 2558 int 2559 readlink(td, uap) 2560 struct thread *td; 2561 register struct readlink_args /* { 2562 char *path; 2563 char *buf; 2564 size_t count; 2565 } */ *uap; 2566 { 2567 2568 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, 2569 UIO_USERSPACE, uap->count)); 2570 } 2571 #ifndef _SYS_SYSPROTO_H_ 2572 struct readlinkat_args { 2573 int fd; 2574 char *path; 2575 char *buf; 2576 size_t bufsize; 2577 }; 2578 #endif 2579 int 2580 readlinkat(struct thread *td, struct readlinkat_args *uap) 2581 { 2582 2583 return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, 2584 uap->buf, UIO_USERSPACE, uap->bufsize)); 2585 } 2586 2587 int 2588 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, 2589 enum uio_seg bufseg, size_t count) 2590 { 2591 2592 return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, 2593 count)); 2594 } 2595 2596 int 2597 kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2598 char *buf, enum uio_seg bufseg, size_t count) 2599 { 2600 struct vnode *vp; 2601 struct iovec aiov; 2602 struct uio auio; 2603 int error; 2604 struct nameidata nd; 2605 int vfslocked; 2606 2607 NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | 2608 AUDITVNODE1, pathseg, path, fd, td); 2609 2610 if ((error = namei(&nd)) != 0) 2611 return (error); 2612 NDFREE(&nd, NDF_ONLY_PNBUF); 2613 vfslocked = NDHASGIANT(&nd); 2614 vp = nd.ni_vp; 2615 #ifdef MAC 2616 error = mac_vnode_check_readlink(td->td_ucred, vp); 2617 if (error) { 2618 vput(vp); 2619 VFS_UNLOCK_GIANT(vfslocked); 2620 return (error); 2621 } 2622 #endif 2623 if (vp->v_type != VLNK) 2624 error = EINVAL; 2625 else { 2626 aiov.iov_base = buf; 2627 aiov.iov_len = count; 2628 auio.uio_iov = &aiov; 2629 auio.uio_iovcnt = 1; 2630 auio.uio_offset = 0; 2631 auio.uio_rw = UIO_READ; 2632 auio.uio_segflg = bufseg; 2633 auio.uio_td = td; 2634 auio.uio_resid = count; 2635 error = VOP_READLINK(vp, &auio, td->td_ucred); 2636 } 2637 vput(vp); 2638 VFS_UNLOCK_GIANT(vfslocked); 2639 td->td_retval[0] = count - auio.uio_resid; 2640 return (error); 2641 } 2642 2643 /* 2644 * Common implementation code for chflags() and fchflags(). 2645 */ 2646 static int 2647 setfflags(td, vp, flags) 2648 struct thread *td; 2649 struct vnode *vp; 2650 int flags; 2651 { 2652 int error; 2653 struct mount *mp; 2654 struct vattr vattr; 2655 2656 /* 2657 * Prevent non-root users from setting flags on devices. When 2658 * a device is reused, users can retain ownership of the device 2659 * if they are allowed to set flags and programs assume that 2660 * chown can't fail when done as root. 2661 */ 2662 if (vp->v_type == VCHR || vp->v_type == VBLK) { 2663 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); 2664 if (error) 2665 return (error); 2666 } 2667 2668 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2669 return (error); 2670 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2671 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2672 VATTR_NULL(&vattr); 2673 vattr.va_flags = flags; 2674 #ifdef MAC 2675 error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); 2676 if (error == 0) 2677 #endif 2678 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2679 VOP_UNLOCK(vp, 0); 2680 vn_finished_write(mp); 2681 return (error); 2682 } 2683 2684 /* 2685 * Change flags of a file given a path name. 2686 */ 2687 #ifndef _SYS_SYSPROTO_H_ 2688 struct chflags_args { 2689 char *path; 2690 int flags; 2691 }; 2692 #endif 2693 int 2694 chflags(td, uap) 2695 struct thread *td; 2696 register struct chflags_args /* { 2697 char *path; 2698 int flags; 2699 } */ *uap; 2700 { 2701 int error; 2702 struct nameidata nd; 2703 int vfslocked; 2704 2705 AUDIT_ARG(fflags, uap->flags); 2706 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2707 uap->path, td); 2708 if ((error = namei(&nd)) != 0) 2709 return (error); 2710 NDFREE(&nd, NDF_ONLY_PNBUF); 2711 vfslocked = NDHASGIANT(&nd); 2712 error = setfflags(td, nd.ni_vp, uap->flags); 2713 vrele(nd.ni_vp); 2714 VFS_UNLOCK_GIANT(vfslocked); 2715 return (error); 2716 } 2717 2718 /* 2719 * Same as chflags() but doesn't follow symlinks. 2720 */ 2721 int 2722 lchflags(td, uap) 2723 struct thread *td; 2724 register struct lchflags_args /* { 2725 char *path; 2726 int flags; 2727 } */ *uap; 2728 { 2729 int error; 2730 struct nameidata nd; 2731 int vfslocked; 2732 2733 AUDIT_ARG(fflags, uap->flags); 2734 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2735 uap->path, td); 2736 if ((error = namei(&nd)) != 0) 2737 return (error); 2738 vfslocked = NDHASGIANT(&nd); 2739 NDFREE(&nd, NDF_ONLY_PNBUF); 2740 error = setfflags(td, nd.ni_vp, uap->flags); 2741 vrele(nd.ni_vp); 2742 VFS_UNLOCK_GIANT(vfslocked); 2743 return (error); 2744 } 2745 2746 /* 2747 * Change flags of a file given a file descriptor. 2748 */ 2749 #ifndef _SYS_SYSPROTO_H_ 2750 struct fchflags_args { 2751 int fd; 2752 int flags; 2753 }; 2754 #endif 2755 int 2756 fchflags(td, uap) 2757 struct thread *td; 2758 register struct fchflags_args /* { 2759 int fd; 2760 int flags; 2761 } */ *uap; 2762 { 2763 struct file *fp; 2764 int vfslocked; 2765 int error; 2766 2767 AUDIT_ARG(fd, uap->fd); 2768 AUDIT_ARG(fflags, uap->flags); 2769 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2770 return (error); 2771 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2772 #ifdef AUDIT 2773 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 2774 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2775 VOP_UNLOCK(fp->f_vnode, 0); 2776 #endif 2777 error = setfflags(td, fp->f_vnode, uap->flags); 2778 VFS_UNLOCK_GIANT(vfslocked); 2779 fdrop(fp, td); 2780 return (error); 2781 } 2782 2783 /* 2784 * Common implementation code for chmod(), lchmod() and fchmod(). 2785 */ 2786 static int 2787 setfmode(td, vp, mode) 2788 struct thread *td; 2789 struct vnode *vp; 2790 int mode; 2791 { 2792 int error; 2793 struct mount *mp; 2794 struct vattr vattr; 2795 2796 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2797 return (error); 2798 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2799 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2800 VATTR_NULL(&vattr); 2801 vattr.va_mode = mode & ALLPERMS; 2802 #ifdef MAC 2803 error = mac_vnode_check_setmode(td->td_ucred, vp, vattr.va_mode); 2804 if (error == 0) 2805 #endif 2806 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2807 VOP_UNLOCK(vp, 0); 2808 vn_finished_write(mp); 2809 return (error); 2810 } 2811 2812 /* 2813 * Change mode of a file given path name. 2814 */ 2815 #ifndef _SYS_SYSPROTO_H_ 2816 struct chmod_args { 2817 char *path; 2818 int mode; 2819 }; 2820 #endif 2821 int 2822 chmod(td, uap) 2823 struct thread *td; 2824 register struct chmod_args /* { 2825 char *path; 2826 int mode; 2827 } */ *uap; 2828 { 2829 2830 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); 2831 } 2832 2833 #ifndef _SYS_SYSPROTO_H_ 2834 struct fchmodat_args { 2835 int dirfd; 2836 char *path; 2837 mode_t mode; 2838 int flag; 2839 } 2840 #endif 2841 int 2842 fchmodat(struct thread *td, struct fchmodat_args *uap) 2843 { 2844 int flag = uap->flag; 2845 int fd = uap->fd; 2846 char *path = uap->path; 2847 mode_t mode = uap->mode; 2848 2849 if (flag & ~AT_SYMLINK_NOFOLLOW) 2850 return (EINVAL); 2851 2852 return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); 2853 } 2854 2855 int 2856 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2857 { 2858 2859 return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); 2860 } 2861 2862 /* 2863 * Change mode of a file given path name (don't follow links.) 2864 */ 2865 #ifndef _SYS_SYSPROTO_H_ 2866 struct lchmod_args { 2867 char *path; 2868 int mode; 2869 }; 2870 #endif 2871 int 2872 lchmod(td, uap) 2873 struct thread *td; 2874 register struct lchmod_args /* { 2875 char *path; 2876 int mode; 2877 } */ *uap; 2878 { 2879 2880 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 2881 uap->mode, AT_SYMLINK_NOFOLLOW)); 2882 } 2883 2884 2885 int 2886 kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2887 mode_t mode, int flag) 2888 { 2889 int error; 2890 struct nameidata nd; 2891 int vfslocked; 2892 int follow; 2893 2894 AUDIT_ARG(mode, mode); 2895 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 2896 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 2897 fd, td); 2898 if ((error = namei(&nd)) != 0) 2899 return (error); 2900 vfslocked = NDHASGIANT(&nd); 2901 NDFREE(&nd, NDF_ONLY_PNBUF); 2902 error = setfmode(td, nd.ni_vp, mode); 2903 vrele(nd.ni_vp); 2904 VFS_UNLOCK_GIANT(vfslocked); 2905 return (error); 2906 } 2907 2908 /* 2909 * Change mode of a file given a file descriptor. 2910 */ 2911 #ifndef _SYS_SYSPROTO_H_ 2912 struct fchmod_args { 2913 int fd; 2914 int mode; 2915 }; 2916 #endif 2917 int 2918 fchmod(td, uap) 2919 struct thread *td; 2920 register struct fchmod_args /* { 2921 int fd; 2922 int mode; 2923 } */ *uap; 2924 { 2925 struct file *fp; 2926 int vfslocked; 2927 int error; 2928 2929 AUDIT_ARG(fd, uap->fd); 2930 AUDIT_ARG(mode, uap->mode); 2931 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 2932 return (error); 2933 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2934 #ifdef AUDIT 2935 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 2936 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 2937 VOP_UNLOCK(fp->f_vnode, 0); 2938 #endif 2939 error = setfmode(td, fp->f_vnode, uap->mode); 2940 VFS_UNLOCK_GIANT(vfslocked); 2941 fdrop(fp, td); 2942 return (error); 2943 } 2944 2945 /* 2946 * Common implementation for chown(), lchown(), and fchown() 2947 */ 2948 static int 2949 setfown(td, vp, uid, gid) 2950 struct thread *td; 2951 struct vnode *vp; 2952 uid_t uid; 2953 gid_t gid; 2954 { 2955 int error; 2956 struct mount *mp; 2957 struct vattr vattr; 2958 2959 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2960 return (error); 2961 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 2962 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2963 VATTR_NULL(&vattr); 2964 vattr.va_uid = uid; 2965 vattr.va_gid = gid; 2966 #ifdef MAC 2967 error = mac_vnode_check_setowner(td->td_ucred, vp, vattr.va_uid, 2968 vattr.va_gid); 2969 if (error == 0) 2970 #endif 2971 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2972 VOP_UNLOCK(vp, 0); 2973 vn_finished_write(mp); 2974 return (error); 2975 } 2976 2977 /* 2978 * Set ownership given a path name. 2979 */ 2980 #ifndef _SYS_SYSPROTO_H_ 2981 struct chown_args { 2982 char *path; 2983 int uid; 2984 int gid; 2985 }; 2986 #endif 2987 int 2988 chown(td, uap) 2989 struct thread *td; 2990 register struct chown_args /* { 2991 char *path; 2992 int uid; 2993 int gid; 2994 } */ *uap; 2995 { 2996 2997 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 2998 } 2999 3000 #ifndef _SYS_SYSPROTO_H_ 3001 struct fchownat_args { 3002 int fd; 3003 const char * path; 3004 uid_t uid; 3005 gid_t gid; 3006 int flag; 3007 }; 3008 #endif 3009 int 3010 fchownat(struct thread *td, struct fchownat_args *uap) 3011 { 3012 int flag; 3013 3014 flag = uap->flag; 3015 if (flag & ~AT_SYMLINK_NOFOLLOW) 3016 return (EINVAL); 3017 3018 return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, 3019 uap->gid, uap->flag)); 3020 } 3021 3022 int 3023 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3024 int gid) 3025 { 3026 3027 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); 3028 } 3029 3030 int 3031 kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3032 int uid, int gid, int flag) 3033 { 3034 struct nameidata nd; 3035 int error, vfslocked, follow; 3036 3037 AUDIT_ARG(owner, uid, gid); 3038 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 3039 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, 3040 fd, td); 3041 3042 if ((error = namei(&nd)) != 0) 3043 return (error); 3044 vfslocked = NDHASGIANT(&nd); 3045 NDFREE(&nd, NDF_ONLY_PNBUF); 3046 error = setfown(td, nd.ni_vp, uid, gid); 3047 vrele(nd.ni_vp); 3048 VFS_UNLOCK_GIANT(vfslocked); 3049 return (error); 3050 } 3051 3052 /* 3053 * Set ownership given a path name, do not cross symlinks. 3054 */ 3055 #ifndef _SYS_SYSPROTO_H_ 3056 struct lchown_args { 3057 char *path; 3058 int uid; 3059 int gid; 3060 }; 3061 #endif 3062 int 3063 lchown(td, uap) 3064 struct thread *td; 3065 register struct lchown_args /* { 3066 char *path; 3067 int uid; 3068 int gid; 3069 } */ *uap; 3070 { 3071 3072 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 3073 } 3074 3075 int 3076 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3077 int gid) 3078 { 3079 3080 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 3081 AT_SYMLINK_NOFOLLOW)); 3082 } 3083 3084 /* 3085 * Set ownership given a file descriptor. 3086 */ 3087 #ifndef _SYS_SYSPROTO_H_ 3088 struct fchown_args { 3089 int fd; 3090 int uid; 3091 int gid; 3092 }; 3093 #endif 3094 int 3095 fchown(td, uap) 3096 struct thread *td; 3097 register struct fchown_args /* { 3098 int fd; 3099 int uid; 3100 int gid; 3101 } */ *uap; 3102 { 3103 struct file *fp; 3104 int vfslocked; 3105 int error; 3106 3107 AUDIT_ARG(fd, uap->fd); 3108 AUDIT_ARG(owner, uap->uid, uap->gid); 3109 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3110 return (error); 3111 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3112 #ifdef AUDIT 3113 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 3114 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3115 VOP_UNLOCK(fp->f_vnode, 0); 3116 #endif 3117 error = setfown(td, fp->f_vnode, uap->uid, uap->gid); 3118 VFS_UNLOCK_GIANT(vfslocked); 3119 fdrop(fp, td); 3120 return (error); 3121 } 3122 3123 /* 3124 * Common implementation code for utimes(), lutimes(), and futimes(). 3125 */ 3126 static int 3127 getutimes(usrtvp, tvpseg, tsp) 3128 const struct timeval *usrtvp; 3129 enum uio_seg tvpseg; 3130 struct timespec *tsp; 3131 { 3132 struct timeval tv[2]; 3133 const struct timeval *tvp; 3134 int error; 3135 3136 if (usrtvp == NULL) { 3137 microtime(&tv[0]); 3138 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 3139 tsp[1] = tsp[0]; 3140 } else { 3141 if (tvpseg == UIO_SYSSPACE) { 3142 tvp = usrtvp; 3143 } else { 3144 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) 3145 return (error); 3146 tvp = tv; 3147 } 3148 3149 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || 3150 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) 3151 return (EINVAL); 3152 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 3153 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 3154 } 3155 return (0); 3156 } 3157 3158 /* 3159 * Common implementation code for utimes(), lutimes(), and futimes(). 3160 */ 3161 static int 3162 setutimes(td, vp, ts, numtimes, nullflag) 3163 struct thread *td; 3164 struct vnode *vp; 3165 const struct timespec *ts; 3166 int numtimes; 3167 int nullflag; 3168 { 3169 int error, setbirthtime; 3170 struct mount *mp; 3171 struct vattr vattr; 3172 3173 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3174 return (error); 3175 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3176 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3177 setbirthtime = 0; 3178 if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && 3179 timespeccmp(&ts[1], &vattr.va_birthtime, < )) 3180 setbirthtime = 1; 3181 VATTR_NULL(&vattr); 3182 vattr.va_atime = ts[0]; 3183 vattr.va_mtime = ts[1]; 3184 if (setbirthtime) 3185 vattr.va_birthtime = ts[1]; 3186 if (numtimes > 2) 3187 vattr.va_birthtime = ts[2]; 3188 if (nullflag) 3189 vattr.va_vaflags |= VA_UTIMES_NULL; 3190 #ifdef MAC 3191 error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, 3192 vattr.va_mtime); 3193 #endif 3194 if (error == 0) 3195 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3196 VOP_UNLOCK(vp, 0); 3197 vn_finished_write(mp); 3198 return (error); 3199 } 3200 3201 /* 3202 * Set the access and modification times of a file. 3203 */ 3204 #ifndef _SYS_SYSPROTO_H_ 3205 struct utimes_args { 3206 char *path; 3207 struct timeval *tptr; 3208 }; 3209 #endif 3210 int 3211 utimes(td, uap) 3212 struct thread *td; 3213 register struct utimes_args /* { 3214 char *path; 3215 struct timeval *tptr; 3216 } */ *uap; 3217 { 3218 3219 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3220 UIO_USERSPACE)); 3221 } 3222 3223 #ifndef _SYS_SYSPROTO_H_ 3224 struct futimesat_args { 3225 int fd; 3226 const char * path; 3227 const struct timeval * times; 3228 }; 3229 #endif 3230 int 3231 futimesat(struct thread *td, struct futimesat_args *uap) 3232 { 3233 3234 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 3235 uap->times, UIO_USERSPACE)); 3236 } 3237 3238 int 3239 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, 3240 struct timeval *tptr, enum uio_seg tptrseg) 3241 { 3242 3243 return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); 3244 } 3245 3246 int 3247 kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3248 struct timeval *tptr, enum uio_seg tptrseg) 3249 { 3250 struct nameidata nd; 3251 struct timespec ts[2]; 3252 int error, vfslocked; 3253 3254 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3255 return (error); 3256 NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, 3257 fd, td); 3258 3259 if ((error = namei(&nd)) != 0) 3260 return (error); 3261 vfslocked = NDHASGIANT(&nd); 3262 NDFREE(&nd, NDF_ONLY_PNBUF); 3263 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3264 vrele(nd.ni_vp); 3265 VFS_UNLOCK_GIANT(vfslocked); 3266 return (error); 3267 } 3268 3269 /* 3270 * Set the access and modification times of a file. 3271 */ 3272 #ifndef _SYS_SYSPROTO_H_ 3273 struct lutimes_args { 3274 char *path; 3275 struct timeval *tptr; 3276 }; 3277 #endif 3278 int 3279 lutimes(td, uap) 3280 struct thread *td; 3281 register struct lutimes_args /* { 3282 char *path; 3283 struct timeval *tptr; 3284 } */ *uap; 3285 { 3286 3287 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3288 UIO_USERSPACE)); 3289 } 3290 3291 int 3292 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, 3293 struct timeval *tptr, enum uio_seg tptrseg) 3294 { 3295 struct timespec ts[2]; 3296 int error; 3297 struct nameidata nd; 3298 int vfslocked; 3299 3300 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3301 return (error); 3302 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3303 if ((error = namei(&nd)) != 0) 3304 return (error); 3305 vfslocked = NDHASGIANT(&nd); 3306 NDFREE(&nd, NDF_ONLY_PNBUF); 3307 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3308 vrele(nd.ni_vp); 3309 VFS_UNLOCK_GIANT(vfslocked); 3310 return (error); 3311 } 3312 3313 /* 3314 * Set the access and modification times of a file. 3315 */ 3316 #ifndef _SYS_SYSPROTO_H_ 3317 struct futimes_args { 3318 int fd; 3319 struct timeval *tptr; 3320 }; 3321 #endif 3322 int 3323 futimes(td, uap) 3324 struct thread *td; 3325 register struct futimes_args /* { 3326 int fd; 3327 struct timeval *tptr; 3328 } */ *uap; 3329 { 3330 3331 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); 3332 } 3333 3334 int 3335 kern_futimes(struct thread *td, int fd, struct timeval *tptr, 3336 enum uio_seg tptrseg) 3337 { 3338 struct timespec ts[2]; 3339 struct file *fp; 3340 int vfslocked; 3341 int error; 3342 3343 AUDIT_ARG(fd, fd); 3344 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3345 return (error); 3346 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 3347 return (error); 3348 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3349 #ifdef AUDIT 3350 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 3351 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1); 3352 VOP_UNLOCK(fp->f_vnode, 0); 3353 #endif 3354 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); 3355 VFS_UNLOCK_GIANT(vfslocked); 3356 fdrop(fp, td); 3357 return (error); 3358 } 3359 3360 /* 3361 * Truncate a file given its path name. 3362 */ 3363 #ifndef _SYS_SYSPROTO_H_ 3364 struct truncate_args { 3365 char *path; 3366 int pad; 3367 off_t length; 3368 }; 3369 #endif 3370 int 3371 truncate(td, uap) 3372 struct thread *td; 3373 register struct truncate_args /* { 3374 char *path; 3375 int pad; 3376 off_t length; 3377 } */ *uap; 3378 { 3379 3380 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); 3381 } 3382 3383 int 3384 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) 3385 { 3386 struct mount *mp; 3387 struct vnode *vp; 3388 struct vattr vattr; 3389 int error; 3390 struct nameidata nd; 3391 int vfslocked; 3392 3393 if (length < 0) 3394 return(EINVAL); 3395 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3396 if ((error = namei(&nd)) != 0) 3397 return (error); 3398 vfslocked = NDHASGIANT(&nd); 3399 vp = nd.ni_vp; 3400 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 3401 vrele(vp); 3402 VFS_UNLOCK_GIANT(vfslocked); 3403 return (error); 3404 } 3405 NDFREE(&nd, NDF_ONLY_PNBUF); 3406 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3407 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3408 if (vp->v_type == VDIR) 3409 error = EISDIR; 3410 #ifdef MAC 3411 else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { 3412 } 3413 #endif 3414 else if ((error = vn_writechk(vp)) == 0 && 3415 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { 3416 VATTR_NULL(&vattr); 3417 vattr.va_size = length; 3418 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3419 } 3420 vput(vp); 3421 vn_finished_write(mp); 3422 VFS_UNLOCK_GIANT(vfslocked); 3423 return (error); 3424 } 3425 3426 #if defined(COMPAT_43) 3427 /* 3428 * Truncate a file given its path name. 3429 */ 3430 #ifndef _SYS_SYSPROTO_H_ 3431 struct otruncate_args { 3432 char *path; 3433 long length; 3434 }; 3435 #endif 3436 int 3437 otruncate(td, uap) 3438 struct thread *td; 3439 register struct otruncate_args /* { 3440 char *path; 3441 long length; 3442 } */ *uap; 3443 { 3444 struct truncate_args /* { 3445 char *path; 3446 int pad; 3447 off_t length; 3448 } */ nuap; 3449 3450 nuap.path = uap->path; 3451 nuap.length = uap->length; 3452 return (truncate(td, &nuap)); 3453 } 3454 #endif /* COMPAT_43 */ 3455 3456 /* Versions with the pad argument */ 3457 int 3458 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) 3459 { 3460 struct truncate_args ouap; 3461 3462 ouap.path = uap->path; 3463 ouap.length = uap->length; 3464 return (truncate(td, &ouap)); 3465 } 3466 3467 int 3468 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) 3469 { 3470 struct ftruncate_args ouap; 3471 3472 ouap.fd = uap->fd; 3473 ouap.length = uap->length; 3474 return (ftruncate(td, &ouap)); 3475 } 3476 3477 /* 3478 * Sync an open file. 3479 */ 3480 #ifndef _SYS_SYSPROTO_H_ 3481 struct fsync_args { 3482 int fd; 3483 }; 3484 #endif 3485 int 3486 fsync(td, uap) 3487 struct thread *td; 3488 struct fsync_args /* { 3489 int fd; 3490 } */ *uap; 3491 { 3492 struct vnode *vp; 3493 struct mount *mp; 3494 struct file *fp; 3495 int vfslocked; 3496 int error; 3497 3498 AUDIT_ARG(fd, uap->fd); 3499 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3500 return (error); 3501 vp = fp->f_vnode; 3502 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3503 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3504 goto drop; 3505 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3506 AUDIT_ARG(vnode, vp, ARG_VNODE1); 3507 if (vp->v_object != NULL) { 3508 VM_OBJECT_LOCK(vp->v_object); 3509 vm_object_page_clean(vp->v_object, 0, 0, 0); 3510 VM_OBJECT_UNLOCK(vp->v_object); 3511 } 3512 error = VOP_FSYNC(vp, MNT_WAIT, td); 3513 3514 VOP_UNLOCK(vp, 0); 3515 vn_finished_write(mp); 3516 drop: 3517 VFS_UNLOCK_GIANT(vfslocked); 3518 fdrop(fp, td); 3519 return (error); 3520 } 3521 3522 /* 3523 * Rename files. Source and destination must either both be directories, or 3524 * both not be directories. If target is a directory, it must be empty. 3525 */ 3526 #ifndef _SYS_SYSPROTO_H_ 3527 struct rename_args { 3528 char *from; 3529 char *to; 3530 }; 3531 #endif 3532 int 3533 rename(td, uap) 3534 struct thread *td; 3535 register struct rename_args /* { 3536 char *from; 3537 char *to; 3538 } */ *uap; 3539 { 3540 3541 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); 3542 } 3543 3544 #ifndef _SYS_SYSPROTO_H_ 3545 struct renameat_args { 3546 int oldfd; 3547 char *old; 3548 int newfd; 3549 char *new; 3550 }; 3551 #endif 3552 int 3553 renameat(struct thread *td, struct renameat_args *uap) 3554 { 3555 3556 return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, 3557 UIO_USERSPACE)); 3558 } 3559 3560 int 3561 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) 3562 { 3563 3564 return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); 3565 } 3566 3567 int 3568 kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, 3569 enum uio_seg pathseg) 3570 { 3571 struct mount *mp = NULL; 3572 struct vnode *tvp, *fvp, *tdvp; 3573 struct nameidata fromnd, tond; 3574 int tvfslocked; 3575 int fvfslocked; 3576 int error; 3577 3578 bwillwrite(); 3579 #ifdef MAC 3580 NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | 3581 AUDITVNODE1, pathseg, old, oldfd, td); 3582 #else 3583 NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | 3584 AUDITVNODE1, pathseg, old, oldfd, td); 3585 #endif 3586 3587 if ((error = namei(&fromnd)) != 0) 3588 return (error); 3589 fvfslocked = NDHASGIANT(&fromnd); 3590 tvfslocked = 0; 3591 #ifdef MAC 3592 error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp, 3593 fromnd.ni_vp, &fromnd.ni_cnd); 3594 VOP_UNLOCK(fromnd.ni_dvp, 0); 3595 if (fromnd.ni_dvp != fromnd.ni_vp) 3596 VOP_UNLOCK(fromnd.ni_vp, 0); 3597 #endif 3598 fvp = fromnd.ni_vp; 3599 if (error == 0) 3600 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); 3601 if (error != 0) { 3602 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3603 vrele(fromnd.ni_dvp); 3604 vrele(fvp); 3605 goto out1; 3606 } 3607 NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | 3608 MPSAFE | AUDITVNODE2, pathseg, new, newfd, td); 3609 if (fromnd.ni_vp->v_type == VDIR) 3610 tond.ni_cnd.cn_flags |= WILLBEDIR; 3611 if ((error = namei(&tond)) != 0) { 3612 /* Translate error code for rename("dir1", "dir2/."). */ 3613 if (error == EISDIR && fvp->v_type == VDIR) 3614 error = EINVAL; 3615 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3616 vrele(fromnd.ni_dvp); 3617 vrele(fvp); 3618 vn_finished_write(mp); 3619 goto out1; 3620 } 3621 tvfslocked = NDHASGIANT(&tond); 3622 tdvp = tond.ni_dvp; 3623 tvp = tond.ni_vp; 3624 if (tvp != NULL) { 3625 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 3626 error = ENOTDIR; 3627 goto out; 3628 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 3629 error = EISDIR; 3630 goto out; 3631 } 3632 } 3633 if (fvp == tdvp) { 3634 error = EINVAL; 3635 goto out; 3636 } 3637 /* 3638 * If the source is the same as the destination (that is, if they 3639 * are links to the same vnode), then there is nothing to do. 3640 */ 3641 if (fvp == tvp) 3642 error = -1; 3643 #ifdef MAC 3644 else 3645 error = mac_vnode_check_rename_to(td->td_ucred, tdvp, 3646 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); 3647 #endif 3648 out: 3649 if (!error) { 3650 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); 3651 if (fromnd.ni_dvp != tdvp) { 3652 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3653 } 3654 if (tvp) { 3655 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); 3656 } 3657 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 3658 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 3659 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3660 NDFREE(&tond, NDF_ONLY_PNBUF); 3661 } else { 3662 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3663 NDFREE(&tond, NDF_ONLY_PNBUF); 3664 if (tvp) 3665 vput(tvp); 3666 if (tdvp == tvp) 3667 vrele(tdvp); 3668 else 3669 vput(tdvp); 3670 vrele(fromnd.ni_dvp); 3671 vrele(fvp); 3672 } 3673 vrele(tond.ni_startdir); 3674 vn_finished_write(mp); 3675 out1: 3676 if (fromnd.ni_startdir) 3677 vrele(fromnd.ni_startdir); 3678 VFS_UNLOCK_GIANT(fvfslocked); 3679 VFS_UNLOCK_GIANT(tvfslocked); 3680 if (error == -1) 3681 return (0); 3682 return (error); 3683 } 3684 3685 /* 3686 * Make a directory file. 3687 */ 3688 #ifndef _SYS_SYSPROTO_H_ 3689 struct mkdir_args { 3690 char *path; 3691 int mode; 3692 }; 3693 #endif 3694 int 3695 mkdir(td, uap) 3696 struct thread *td; 3697 register struct mkdir_args /* { 3698 char *path; 3699 int mode; 3700 } */ *uap; 3701 { 3702 3703 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); 3704 } 3705 3706 #ifndef _SYS_SYSPROTO_H_ 3707 struct mkdirat_args { 3708 int fd; 3709 char *path; 3710 mode_t mode; 3711 }; 3712 #endif 3713 int 3714 mkdirat(struct thread *td, struct mkdirat_args *uap) 3715 { 3716 3717 return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); 3718 } 3719 3720 int 3721 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) 3722 { 3723 3724 return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); 3725 } 3726 3727 int 3728 kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, 3729 int mode) 3730 { 3731 struct mount *mp; 3732 struct vnode *vp; 3733 struct vattr vattr; 3734 int error; 3735 struct nameidata nd; 3736 int vfslocked; 3737 3738 AUDIT_ARG(mode, mode); 3739 restart: 3740 bwillwrite(); 3741 NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, 3742 segflg, path, fd, td); 3743 nd.ni_cnd.cn_flags |= WILLBEDIR; 3744 if ((error = namei(&nd)) != 0) 3745 return (error); 3746 vfslocked = NDHASGIANT(&nd); 3747 vp = nd.ni_vp; 3748 if (vp != NULL) { 3749 NDFREE(&nd, NDF_ONLY_PNBUF); 3750 /* 3751 * XXX namei called with LOCKPARENT but not LOCKLEAF has 3752 * the strange behaviour of leaving the vnode unlocked 3753 * if the target is the same vnode as the parent. 3754 */ 3755 if (vp == nd.ni_dvp) 3756 vrele(nd.ni_dvp); 3757 else 3758 vput(nd.ni_dvp); 3759 vrele(vp); 3760 VFS_UNLOCK_GIANT(vfslocked); 3761 return (EEXIST); 3762 } 3763 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3764 NDFREE(&nd, NDF_ONLY_PNBUF); 3765 vput(nd.ni_dvp); 3766 VFS_UNLOCK_GIANT(vfslocked); 3767 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3768 return (error); 3769 goto restart; 3770 } 3771 VATTR_NULL(&vattr); 3772 vattr.va_type = VDIR; 3773 FILEDESC_SLOCK(td->td_proc->p_fd); 3774 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; 3775 FILEDESC_SUNLOCK(td->td_proc->p_fd); 3776 #ifdef MAC 3777 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 3778 &vattr); 3779 if (error) 3780 goto out; 3781 #endif 3782 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3783 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 3784 #ifdef MAC 3785 out: 3786 #endif 3787 NDFREE(&nd, NDF_ONLY_PNBUF); 3788 vput(nd.ni_dvp); 3789 if (!error) 3790 vput(nd.ni_vp); 3791 vn_finished_write(mp); 3792 VFS_UNLOCK_GIANT(vfslocked); 3793 return (error); 3794 } 3795 3796 /* 3797 * Remove a directory file. 3798 */ 3799 #ifndef _SYS_SYSPROTO_H_ 3800 struct rmdir_args { 3801 char *path; 3802 }; 3803 #endif 3804 int 3805 rmdir(td, uap) 3806 struct thread *td; 3807 struct rmdir_args /* { 3808 char *path; 3809 } */ *uap; 3810 { 3811 3812 return (kern_rmdir(td, uap->path, UIO_USERSPACE)); 3813 } 3814 3815 int 3816 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) 3817 { 3818 3819 return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); 3820 } 3821 3822 int 3823 kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 3824 { 3825 struct mount *mp; 3826 struct vnode *vp; 3827 int error; 3828 struct nameidata nd; 3829 int vfslocked; 3830 3831 restart: 3832 bwillwrite(); 3833 NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, 3834 pathseg, path, fd, td); 3835 if ((error = namei(&nd)) != 0) 3836 return (error); 3837 vfslocked = NDHASGIANT(&nd); 3838 vp = nd.ni_vp; 3839 if (vp->v_type != VDIR) { 3840 error = ENOTDIR; 3841 goto out; 3842 } 3843 /* 3844 * No rmdir "." please. 3845 */ 3846 if (nd.ni_dvp == vp) { 3847 error = EINVAL; 3848 goto out; 3849 } 3850 /* 3851 * The root of a mounted filesystem cannot be deleted. 3852 */ 3853 if (vp->v_vflag & VV_ROOT) { 3854 error = EBUSY; 3855 goto out; 3856 } 3857 #ifdef MAC 3858 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 3859 &nd.ni_cnd); 3860 if (error) 3861 goto out; 3862 #endif 3863 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3864 NDFREE(&nd, NDF_ONLY_PNBUF); 3865 vput(vp); 3866 if (nd.ni_dvp == vp) 3867 vrele(nd.ni_dvp); 3868 else 3869 vput(nd.ni_dvp); 3870 VFS_UNLOCK_GIANT(vfslocked); 3871 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3872 return (error); 3873 goto restart; 3874 } 3875 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); 3876 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 3877 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 3878 vn_finished_write(mp); 3879 out: 3880 NDFREE(&nd, NDF_ONLY_PNBUF); 3881 vput(vp); 3882 if (nd.ni_dvp == vp) 3883 vrele(nd.ni_dvp); 3884 else 3885 vput(nd.ni_dvp); 3886 VFS_UNLOCK_GIANT(vfslocked); 3887 return (error); 3888 } 3889 3890 #ifdef COMPAT_43 3891 /* 3892 * Read a block of directory entries in a filesystem independent format. 3893 */ 3894 #ifndef _SYS_SYSPROTO_H_ 3895 struct ogetdirentries_args { 3896 int fd; 3897 char *buf; 3898 u_int count; 3899 long *basep; 3900 }; 3901 #endif 3902 int 3903 ogetdirentries(td, uap) 3904 struct thread *td; 3905 register struct ogetdirentries_args /* { 3906 int fd; 3907 char *buf; 3908 u_int count; 3909 long *basep; 3910 } */ *uap; 3911 { 3912 struct vnode *vp; 3913 struct file *fp; 3914 struct uio auio, kuio; 3915 struct iovec aiov, kiov; 3916 struct dirent *dp, *edp; 3917 caddr_t dirbuf; 3918 int error, eofflag, readcnt, vfslocked; 3919 long loff; 3920 3921 /* XXX arbitrary sanity limit on `count'. */ 3922 if (uap->count > 64 * 1024) 3923 return (EINVAL); 3924 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) 3925 return (error); 3926 if ((fp->f_flag & FREAD) == 0) { 3927 fdrop(fp, td); 3928 return (EBADF); 3929 } 3930 vp = fp->f_vnode; 3931 unionread: 3932 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3933 if (vp->v_type != VDIR) { 3934 VFS_UNLOCK_GIANT(vfslocked); 3935 fdrop(fp, td); 3936 return (EINVAL); 3937 } 3938 aiov.iov_base = uap->buf; 3939 aiov.iov_len = uap->count; 3940 auio.uio_iov = &aiov; 3941 auio.uio_iovcnt = 1; 3942 auio.uio_rw = UIO_READ; 3943 auio.uio_segflg = UIO_USERSPACE; 3944 auio.uio_td = td; 3945 auio.uio_resid = uap->count; 3946 vn_lock(vp, LK_SHARED | LK_RETRY); 3947 loff = auio.uio_offset = fp->f_offset; 3948 #ifdef MAC 3949 error = mac_vnode_check_readdir(td->td_ucred, vp); 3950 if (error) { 3951 VOP_UNLOCK(vp, 0); 3952 VFS_UNLOCK_GIANT(vfslocked); 3953 fdrop(fp, td); 3954 return (error); 3955 } 3956 #endif 3957 # if (BYTE_ORDER != LITTLE_ENDIAN) 3958 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 3959 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 3960 NULL, NULL); 3961 fp->f_offset = auio.uio_offset; 3962 } else 3963 # endif 3964 { 3965 kuio = auio; 3966 kuio.uio_iov = &kiov; 3967 kuio.uio_segflg = UIO_SYSSPACE; 3968 kiov.iov_len = uap->count; 3969 dirbuf = malloc(uap->count, M_TEMP, M_WAITOK); 3970 kiov.iov_base = dirbuf; 3971 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 3972 NULL, NULL); 3973 fp->f_offset = kuio.uio_offset; 3974 if (error == 0) { 3975 readcnt = uap->count - kuio.uio_resid; 3976 edp = (struct dirent *)&dirbuf[readcnt]; 3977 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 3978 # if (BYTE_ORDER == LITTLE_ENDIAN) 3979 /* 3980 * The expected low byte of 3981 * dp->d_namlen is our dp->d_type. 3982 * The high MBZ byte of dp->d_namlen 3983 * is our dp->d_namlen. 3984 */ 3985 dp->d_type = dp->d_namlen; 3986 dp->d_namlen = 0; 3987 # else 3988 /* 3989 * The dp->d_type is the high byte 3990 * of the expected dp->d_namlen, 3991 * so must be zero'ed. 3992 */ 3993 dp->d_type = 0; 3994 # endif 3995 if (dp->d_reclen > 0) { 3996 dp = (struct dirent *) 3997 ((char *)dp + dp->d_reclen); 3998 } else { 3999 error = EIO; 4000 break; 4001 } 4002 } 4003 if (dp >= edp) 4004 error = uiomove(dirbuf, readcnt, &auio); 4005 } 4006 free(dirbuf, M_TEMP); 4007 } 4008 if (error) { 4009 VOP_UNLOCK(vp, 0); 4010 VFS_UNLOCK_GIANT(vfslocked); 4011 fdrop(fp, td); 4012 return (error); 4013 } 4014 if (uap->count == auio.uio_resid && 4015 (vp->v_vflag & VV_ROOT) && 4016 (vp->v_mount->mnt_flag & MNT_UNION)) { 4017 struct vnode *tvp = vp; 4018 vp = vp->v_mount->mnt_vnodecovered; 4019 VREF(vp); 4020 fp->f_vnode = vp; 4021 fp->f_data = vp; 4022 fp->f_offset = 0; 4023 vput(tvp); 4024 VFS_UNLOCK_GIANT(vfslocked); 4025 goto unionread; 4026 } 4027 VOP_UNLOCK(vp, 0); 4028 VFS_UNLOCK_GIANT(vfslocked); 4029 error = copyout(&loff, uap->basep, sizeof(long)); 4030 fdrop(fp, td); 4031 td->td_retval[0] = uap->count - auio.uio_resid; 4032 return (error); 4033 } 4034 #endif /* COMPAT_43 */ 4035 4036 /* 4037 * Read a block of directory entries in a filesystem independent format. 4038 */ 4039 #ifndef _SYS_SYSPROTO_H_ 4040 struct getdirentries_args { 4041 int fd; 4042 char *buf; 4043 u_int count; 4044 long *basep; 4045 }; 4046 #endif 4047 int 4048 getdirentries(td, uap) 4049 struct thread *td; 4050 register struct getdirentries_args /* { 4051 int fd; 4052 char *buf; 4053 u_int count; 4054 long *basep; 4055 } */ *uap; 4056 { 4057 long base; 4058 int error; 4059 4060 error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); 4061 if (error) 4062 return (error); 4063 if (uap->basep != NULL) 4064 error = copyout(&base, uap->basep, sizeof(long)); 4065 return (error); 4066 } 4067 4068 int 4069 kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, 4070 long *basep) 4071 { 4072 struct vnode *vp; 4073 struct file *fp; 4074 struct uio auio; 4075 struct iovec aiov; 4076 int vfslocked; 4077 long loff; 4078 int error, eofflag; 4079 4080 AUDIT_ARG(fd, fd); 4081 if (count > INT_MAX) 4082 return (EINVAL); 4083 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) 4084 return (error); 4085 if ((fp->f_flag & FREAD) == 0) { 4086 fdrop(fp, td); 4087 return (EBADF); 4088 } 4089 vp = fp->f_vnode; 4090 unionread: 4091 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 4092 if (vp->v_type != VDIR) { 4093 VFS_UNLOCK_GIANT(vfslocked); 4094 error = EINVAL; 4095 goto fail; 4096 } 4097 aiov.iov_base = buf; 4098 aiov.iov_len = count; 4099 auio.uio_iov = &aiov; 4100 auio.uio_iovcnt = 1; 4101 auio.uio_rw = UIO_READ; 4102 auio.uio_segflg = UIO_USERSPACE; 4103 auio.uio_td = td; 4104 auio.uio_resid = count; 4105 vn_lock(vp, LK_SHARED | LK_RETRY); 4106 AUDIT_ARG(vnode, vp, ARG_VNODE1); 4107 loff = auio.uio_offset = fp->f_offset; 4108 #ifdef MAC 4109 error = mac_vnode_check_readdir(td->td_ucred, vp); 4110 if (error == 0) 4111 #endif 4112 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, 4113 NULL); 4114 fp->f_offset = auio.uio_offset; 4115 if (error) { 4116 VOP_UNLOCK(vp, 0); 4117 VFS_UNLOCK_GIANT(vfslocked); 4118 goto fail; 4119 } 4120 if (count == auio.uio_resid && 4121 (vp->v_vflag & VV_ROOT) && 4122 (vp->v_mount->mnt_flag & MNT_UNION)) { 4123 struct vnode *tvp = vp; 4124 vp = vp->v_mount->mnt_vnodecovered; 4125 VREF(vp); 4126 fp->f_vnode = vp; 4127 fp->f_data = vp; 4128 fp->f_offset = 0; 4129 vput(tvp); 4130 VFS_UNLOCK_GIANT(vfslocked); 4131 goto unionread; 4132 } 4133 VOP_UNLOCK(vp, 0); 4134 VFS_UNLOCK_GIANT(vfslocked); 4135 *basep = loff; 4136 td->td_retval[0] = count - auio.uio_resid; 4137 fail: 4138 fdrop(fp, td); 4139 return (error); 4140 } 4141 4142 #ifndef _SYS_SYSPROTO_H_ 4143 struct getdents_args { 4144 int fd; 4145 char *buf; 4146 size_t count; 4147 }; 4148 #endif 4149 int 4150 getdents(td, uap) 4151 struct thread *td; 4152 register struct getdents_args /* { 4153 int fd; 4154 char *buf; 4155 u_int count; 4156 } */ *uap; 4157 { 4158 struct getdirentries_args ap; 4159 ap.fd = uap->fd; 4160 ap.buf = uap->buf; 4161 ap.count = uap->count; 4162 ap.basep = NULL; 4163 return (getdirentries(td, &ap)); 4164 } 4165 4166 /* 4167 * Set the mode mask for creation of filesystem nodes. 4168 */ 4169 #ifndef _SYS_SYSPROTO_H_ 4170 struct umask_args { 4171 int newmask; 4172 }; 4173 #endif 4174 int 4175 umask(td, uap) 4176 struct thread *td; 4177 struct umask_args /* { 4178 int newmask; 4179 } */ *uap; 4180 { 4181 register struct filedesc *fdp; 4182 4183 FILEDESC_XLOCK(td->td_proc->p_fd); 4184 fdp = td->td_proc->p_fd; 4185 td->td_retval[0] = fdp->fd_cmask; 4186 fdp->fd_cmask = uap->newmask & ALLPERMS; 4187 FILEDESC_XUNLOCK(td->td_proc->p_fd); 4188 return (0); 4189 } 4190 4191 /* 4192 * Void all references to file by ripping underlying filesystem away from 4193 * vnode. 4194 */ 4195 #ifndef _SYS_SYSPROTO_H_ 4196 struct revoke_args { 4197 char *path; 4198 }; 4199 #endif 4200 int 4201 revoke(td, uap) 4202 struct thread *td; 4203 register struct revoke_args /* { 4204 char *path; 4205 } */ *uap; 4206 { 4207 struct vnode *vp; 4208 struct vattr vattr; 4209 int error; 4210 struct nameidata nd; 4211 int vfslocked; 4212 4213 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4214 UIO_USERSPACE, uap->path, td); 4215 if ((error = namei(&nd)) != 0) 4216 return (error); 4217 vfslocked = NDHASGIANT(&nd); 4218 vp = nd.ni_vp; 4219 NDFREE(&nd, NDF_ONLY_PNBUF); 4220 if (vp->v_type != VCHR) { 4221 error = EINVAL; 4222 goto out; 4223 } 4224 #ifdef MAC 4225 error = mac_vnode_check_revoke(td->td_ucred, vp); 4226 if (error) 4227 goto out; 4228 #endif 4229 error = VOP_GETATTR(vp, &vattr, td->td_ucred); 4230 if (error) 4231 goto out; 4232 if (td->td_ucred->cr_uid != vattr.va_uid) { 4233 error = priv_check(td, PRIV_VFS_ADMIN); 4234 if (error) 4235 goto out; 4236 } 4237 if (vcount(vp) > 1) 4238 VOP_REVOKE(vp, REVOKEALL); 4239 out: 4240 vput(vp); 4241 VFS_UNLOCK_GIANT(vfslocked); 4242 return (error); 4243 } 4244 4245 /* 4246 * Convert a user file descriptor to a kernel file entry. 4247 * A reference on the file entry is held upon returning. 4248 */ 4249 int 4250 getvnode(fdp, fd, fpp) 4251 struct filedesc *fdp; 4252 int fd; 4253 struct file **fpp; 4254 { 4255 int error; 4256 struct file *fp; 4257 4258 fp = NULL; 4259 if (fdp == NULL) 4260 error = EBADF; 4261 else { 4262 FILEDESC_SLOCK(fdp); 4263 if ((u_int)fd >= fdp->fd_nfiles || 4264 (fp = fdp->fd_ofiles[fd]) == NULL) 4265 error = EBADF; 4266 else if (fp->f_vnode == NULL) { 4267 fp = NULL; 4268 error = EINVAL; 4269 } else { 4270 fhold(fp); 4271 error = 0; 4272 } 4273 FILEDESC_SUNLOCK(fdp); 4274 } 4275 *fpp = fp; 4276 return (error); 4277 } 4278 4279 /* 4280 * Get an (NFS) file handle. 4281 */ 4282 #ifndef _SYS_SYSPROTO_H_ 4283 struct lgetfh_args { 4284 char *fname; 4285 fhandle_t *fhp; 4286 }; 4287 #endif 4288 int 4289 lgetfh(td, uap) 4290 struct thread *td; 4291 register struct lgetfh_args *uap; 4292 { 4293 struct nameidata nd; 4294 fhandle_t fh; 4295 register struct vnode *vp; 4296 int vfslocked; 4297 int error; 4298 4299 error = priv_check(td, PRIV_VFS_GETFH); 4300 if (error) 4301 return (error); 4302 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4303 UIO_USERSPACE, uap->fname, td); 4304 error = namei(&nd); 4305 if (error) 4306 return (error); 4307 vfslocked = NDHASGIANT(&nd); 4308 NDFREE(&nd, NDF_ONLY_PNBUF); 4309 vp = nd.ni_vp; 4310 bzero(&fh, sizeof(fh)); 4311 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4312 error = VOP_VPTOFH(vp, &fh.fh_fid); 4313 vput(vp); 4314 VFS_UNLOCK_GIANT(vfslocked); 4315 if (error) 4316 return (error); 4317 error = copyout(&fh, uap->fhp, sizeof (fh)); 4318 return (error); 4319 } 4320 4321 #ifndef _SYS_SYSPROTO_H_ 4322 struct getfh_args { 4323 char *fname; 4324 fhandle_t *fhp; 4325 }; 4326 #endif 4327 int 4328 getfh(td, uap) 4329 struct thread *td; 4330 register struct getfh_args *uap; 4331 { 4332 struct nameidata nd; 4333 fhandle_t fh; 4334 register struct vnode *vp; 4335 int vfslocked; 4336 int error; 4337 4338 error = priv_check(td, PRIV_VFS_GETFH); 4339 if (error) 4340 return (error); 4341 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4342 UIO_USERSPACE, uap->fname, td); 4343 error = namei(&nd); 4344 if (error) 4345 return (error); 4346 vfslocked = NDHASGIANT(&nd); 4347 NDFREE(&nd, NDF_ONLY_PNBUF); 4348 vp = nd.ni_vp; 4349 bzero(&fh, sizeof(fh)); 4350 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4351 error = VOP_VPTOFH(vp, &fh.fh_fid); 4352 vput(vp); 4353 VFS_UNLOCK_GIANT(vfslocked); 4354 if (error) 4355 return (error); 4356 error = copyout(&fh, uap->fhp, sizeof (fh)); 4357 return (error); 4358 } 4359 4360 /* 4361 * syscall for the rpc.lockd to use to translate a NFS file handle into an 4362 * open descriptor. 4363 * 4364 * warning: do not remove the priv_check() call or this becomes one giant 4365 * security hole. 4366 */ 4367 #ifndef _SYS_SYSPROTO_H_ 4368 struct fhopen_args { 4369 const struct fhandle *u_fhp; 4370 int flags; 4371 }; 4372 #endif 4373 int 4374 fhopen(td, uap) 4375 struct thread *td; 4376 struct fhopen_args /* { 4377 const struct fhandle *u_fhp; 4378 int flags; 4379 } */ *uap; 4380 { 4381 struct proc *p = td->td_proc; 4382 struct mount *mp; 4383 struct vnode *vp; 4384 struct fhandle fhp; 4385 struct vattr vat; 4386 struct vattr *vap = &vat; 4387 struct flock lf; 4388 struct file *fp; 4389 register struct filedesc *fdp = p->p_fd; 4390 int fmode, error, type; 4391 accmode_t accmode; 4392 struct file *nfp; 4393 int vfslocked; 4394 int indx; 4395 4396 error = priv_check(td, PRIV_VFS_FHOPEN); 4397 if (error) 4398 return (error); 4399 fmode = FFLAGS(uap->flags); 4400 /* why not allow a non-read/write open for our lockd? */ 4401 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 4402 return (EINVAL); 4403 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 4404 if (error) 4405 return(error); 4406 /* find the mount point */ 4407 mp = vfs_busyfs(&fhp.fh_fsid); 4408 if (mp == NULL) 4409 return (ESTALE); 4410 vfslocked = VFS_LOCK_GIANT(mp); 4411 /* now give me my vnode, it gets returned to me locked */ 4412 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 4413 vfs_unbusy(mp); 4414 if (error) 4415 goto out; 4416 /* 4417 * from now on we have to make sure not 4418 * to forget about the vnode 4419 * any error that causes an abort must vput(vp) 4420 * just set error = err and 'goto bad;'. 4421 */ 4422 4423 /* 4424 * from vn_open 4425 */ 4426 if (vp->v_type == VLNK) { 4427 error = EMLINK; 4428 goto bad; 4429 } 4430 if (vp->v_type == VSOCK) { 4431 error = EOPNOTSUPP; 4432 goto bad; 4433 } 4434 accmode = 0; 4435 if (fmode & (FWRITE | O_TRUNC)) { 4436 if (vp->v_type == VDIR) { 4437 error = EISDIR; 4438 goto bad; 4439 } 4440 error = vn_writechk(vp); 4441 if (error) 4442 goto bad; 4443 accmode |= VWRITE; 4444 } 4445 if (fmode & FREAD) 4446 accmode |= VREAD; 4447 if (fmode & O_APPEND) 4448 accmode |= VAPPEND; 4449 #ifdef MAC 4450 error = mac_vnode_check_open(td->td_ucred, vp, accmode); 4451 if (error) 4452 goto bad; 4453 #endif 4454 if (accmode) { 4455 error = VOP_ACCESS(vp, accmode, td->td_ucred, td); 4456 if (error) 4457 goto bad; 4458 } 4459 if (fmode & O_TRUNC) { 4460 VOP_UNLOCK(vp, 0); /* XXX */ 4461 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) { 4462 vrele(vp); 4463 goto out; 4464 } 4465 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); 4466 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ 4467 #ifdef MAC 4468 /* 4469 * We don't yet have fp->f_cred, so use td->td_ucred, which 4470 * should be right. 4471 */ 4472 error = mac_vnode_check_write(td->td_ucred, td->td_ucred, vp); 4473 if (error == 0) { 4474 #endif 4475 VATTR_NULL(vap); 4476 vap->va_size = 0; 4477 error = VOP_SETATTR(vp, vap, td->td_ucred); 4478 #ifdef MAC 4479 } 4480 #endif 4481 vn_finished_write(mp); 4482 if (error) 4483 goto bad; 4484 } 4485 error = VOP_OPEN(vp, fmode, td->td_ucred, td, NULL); 4486 if (error) 4487 goto bad; 4488 4489 if (fmode & FWRITE) 4490 vp->v_writecount++; 4491 4492 /* 4493 * end of vn_open code 4494 */ 4495 4496 if ((error = falloc(td, &nfp, &indx)) != 0) { 4497 if (fmode & FWRITE) 4498 vp->v_writecount--; 4499 goto bad; 4500 } 4501 /* An extra reference on `nfp' has been held for us by falloc(). */ 4502 fp = nfp; 4503 nfp->f_vnode = vp; 4504 finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops); 4505 if (fmode & (O_EXLOCK | O_SHLOCK)) { 4506 lf.l_whence = SEEK_SET; 4507 lf.l_start = 0; 4508 lf.l_len = 0; 4509 if (fmode & O_EXLOCK) 4510 lf.l_type = F_WRLCK; 4511 else 4512 lf.l_type = F_RDLCK; 4513 type = F_FLOCK; 4514 if ((fmode & FNONBLOCK) == 0) 4515 type |= F_WAIT; 4516 VOP_UNLOCK(vp, 0); 4517 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, 4518 type)) != 0) { 4519 /* 4520 * The lock request failed. Normally close the 4521 * descriptor but handle the case where someone might 4522 * have dup()d or close()d it when we weren't looking. 4523 */ 4524 fdclose(fdp, fp, indx, td); 4525 4526 /* 4527 * release our private reference 4528 */ 4529 fdrop(fp, td); 4530 goto out; 4531 } 4532 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 4533 atomic_set_int(&fp->f_flag, FHASLOCK); 4534 } 4535 4536 VOP_UNLOCK(vp, 0); 4537 fdrop(fp, td); 4538 vfs_rel(mp); 4539 VFS_UNLOCK_GIANT(vfslocked); 4540 td->td_retval[0] = indx; 4541 return (0); 4542 4543 bad: 4544 vput(vp); 4545 out: 4546 VFS_UNLOCK_GIANT(vfslocked); 4547 return (error); 4548 } 4549 4550 /* 4551 * Stat an (NFS) file handle. 4552 */ 4553 #ifndef _SYS_SYSPROTO_H_ 4554 struct fhstat_args { 4555 struct fhandle *u_fhp; 4556 struct stat *sb; 4557 }; 4558 #endif 4559 int 4560 fhstat(td, uap) 4561 struct thread *td; 4562 register struct fhstat_args /* { 4563 struct fhandle *u_fhp; 4564 struct stat *sb; 4565 } */ *uap; 4566 { 4567 struct stat sb; 4568 fhandle_t fh; 4569 struct mount *mp; 4570 struct vnode *vp; 4571 int vfslocked; 4572 int error; 4573 4574 error = priv_check(td, PRIV_VFS_FHSTAT); 4575 if (error) 4576 return (error); 4577 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4578 if (error) 4579 return (error); 4580 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) 4581 return (ESTALE); 4582 vfslocked = VFS_LOCK_GIANT(mp); 4583 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); 4584 vfs_unbusy(mp); 4585 if (error) { 4586 VFS_UNLOCK_GIANT(vfslocked); 4587 return (error); 4588 } 4589 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 4590 vput(vp); 4591 VFS_UNLOCK_GIANT(vfslocked); 4592 if (error) 4593 return (error); 4594 error = copyout(&sb, uap->sb, sizeof(sb)); 4595 return (error); 4596 } 4597 4598 /* 4599 * Implement fstatfs() for (NFS) file handles. 4600 */ 4601 #ifndef _SYS_SYSPROTO_H_ 4602 struct fhstatfs_args { 4603 struct fhandle *u_fhp; 4604 struct statfs *buf; 4605 }; 4606 #endif 4607 int 4608 fhstatfs(td, uap) 4609 struct thread *td; 4610 struct fhstatfs_args /* { 4611 struct fhandle *u_fhp; 4612 struct statfs *buf; 4613 } */ *uap; 4614 { 4615 struct statfs sf; 4616 fhandle_t fh; 4617 int error; 4618 4619 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4620 if (error) 4621 return (error); 4622 error = kern_fhstatfs(td, fh, &sf); 4623 if (error) 4624 return (error); 4625 return (copyout(&sf, uap->buf, sizeof(sf))); 4626 } 4627 4628 int 4629 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) 4630 { 4631 struct statfs *sp; 4632 struct mount *mp; 4633 struct vnode *vp; 4634 int vfslocked; 4635 int error; 4636 4637 error = priv_check(td, PRIV_VFS_FHSTATFS); 4638 if (error) 4639 return (error); 4640 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) 4641 return (ESTALE); 4642 vfslocked = VFS_LOCK_GIANT(mp); 4643 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); 4644 if (error) { 4645 vfs_unbusy(mp); 4646 VFS_UNLOCK_GIANT(vfslocked); 4647 return (error); 4648 } 4649 vput(vp); 4650 error = prison_canseemount(td->td_ucred, mp); 4651 if (error) 4652 goto out; 4653 #ifdef MAC 4654 error = mac_mount_check_stat(td->td_ucred, mp); 4655 if (error) 4656 goto out; 4657 #endif 4658 /* 4659 * Set these in case the underlying filesystem fails to do so. 4660 */ 4661 sp = &mp->mnt_stat; 4662 sp->f_version = STATFS_VERSION; 4663 sp->f_namemax = NAME_MAX; 4664 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 4665 error = VFS_STATFS(mp, sp, td); 4666 if (error == 0) 4667 *buf = *sp; 4668 out: 4669 vfs_unbusy(mp); 4670 VFS_UNLOCK_GIANT(vfslocked); 4671 return (error); 4672 } 4673