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