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