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