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