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