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 if (flags & O_EXEC) { 1010 rights |= CAP_FEXECVE; 1011 } else { 1012 switch ((flags & O_ACCMODE)) { 1013 case O_RDONLY: 1014 rights |= CAP_READ; 1015 break; 1016 case O_RDWR: 1017 rights |= CAP_READ; 1018 /* FALLTHROUGH */ 1019 case O_WRONLY: 1020 rights |= CAP_WRITE; 1021 break; 1022 } 1023 } 1024 1025 if (flags & O_CREAT) 1026 rights |= CAP_CREATE; 1027 1028 if (flags & O_TRUNC) 1029 rights |= CAP_FTRUNCATE; 1030 1031 if ((flags & O_EXLOCK) || (flags & O_SHLOCK)) 1032 rights |= CAP_FLOCK; 1033 1034 return (rights); 1035 } 1036 1037 /* 1038 * Check permissions, allocate an open file structure, and call the device 1039 * open routine if any. 1040 */ 1041 #ifndef _SYS_SYSPROTO_H_ 1042 struct open_args { 1043 char *path; 1044 int flags; 1045 int mode; 1046 }; 1047 #endif 1048 int 1049 sys_open(td, uap) 1050 struct thread *td; 1051 register struct open_args /* { 1052 char *path; 1053 int flags; 1054 int mode; 1055 } */ *uap; 1056 { 1057 1058 return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); 1059 } 1060 1061 #ifndef _SYS_SYSPROTO_H_ 1062 struct openat_args { 1063 int fd; 1064 char *path; 1065 int flag; 1066 int mode; 1067 }; 1068 #endif 1069 int 1070 sys_openat(struct thread *td, struct openat_args *uap) 1071 { 1072 1073 return (kern_openat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, 1074 uap->mode)); 1075 } 1076 1077 int 1078 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, 1079 int mode) 1080 { 1081 1082 return (kern_openat(td, AT_FDCWD, path, pathseg, flags, mode)); 1083 } 1084 1085 int 1086 kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1087 int flags, int mode) 1088 { 1089 struct proc *p = td->td_proc; 1090 struct filedesc *fdp = p->p_fd; 1091 struct file *fp; 1092 struct vnode *vp; 1093 int cmode; 1094 int indx = -1, error; 1095 struct nameidata nd; 1096 int vfslocked; 1097 cap_rights_t rights_needed = CAP_LOOKUP; 1098 1099 AUDIT_ARG_FFLAGS(flags); 1100 AUDIT_ARG_MODE(mode); 1101 /* XXX: audit dirfd */ 1102 rights_needed |= flags_to_rights(flags); 1103 /* 1104 * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags 1105 * may be specified. 1106 */ 1107 if (flags & O_EXEC) { 1108 if (flags & O_ACCMODE) 1109 return (EINVAL); 1110 } else if ((flags & O_ACCMODE) == O_ACCMODE) { 1111 return (EINVAL); 1112 } else { 1113 flags = FFLAGS(flags); 1114 } 1115 1116 /* 1117 * Allocate the file descriptor, but don't install a descriptor yet. 1118 */ 1119 error = falloc_noinstall(td, &fp); 1120 if (error) 1121 return (error); 1122 /* 1123 * An extra reference on `fp' has been held for us by 1124 * falloc_noinstall(). 1125 */ 1126 /* Set the flags early so the finit in devfs can pick them up. */ 1127 fp->f_flag = flags & FMASK; 1128 cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 1129 NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, 1130 path, fd, rights_needed, td); 1131 td->td_dupfd = -1; /* XXX check for fdopen */ 1132 error = vn_open(&nd, &flags, cmode, fp); 1133 if (error) { 1134 /* 1135 * If the vn_open replaced the method vector, something 1136 * wonderous happened deep below and we just pass it up 1137 * pretending we know what we do. 1138 */ 1139 if (error == ENXIO && fp->f_ops != &badfileops) 1140 goto success; 1141 1142 /* 1143 * Handle special fdopen() case. bleh. 1144 * 1145 * Don't do this for relative (capability) lookups; we don't 1146 * understand exactly what would happen, and we don't think 1147 * that it ever should. 1148 */ 1149 if (nd.ni_strictrelative == 0 && 1150 (error == ENODEV || error == ENXIO) && 1151 td->td_dupfd >= 0) { 1152 error = dupfdopen(td, fdp, td->td_dupfd, flags, error, 1153 &indx); 1154 if (error == 0) 1155 goto success; 1156 } 1157 1158 if (error == ERESTART) 1159 error = EINTR; 1160 goto bad_unlocked; 1161 } 1162 td->td_dupfd = 0; 1163 vfslocked = NDHASGIANT(&nd); 1164 NDFREE(&nd, NDF_ONLY_PNBUF); 1165 vp = nd.ni_vp; 1166 1167 /* 1168 * Store the vnode, for any f_type. Typically, the vnode use 1169 * count is decremented by direct call to vn_closefile() for 1170 * files that switched type in the cdevsw fdopen() method. 1171 */ 1172 fp->f_vnode = vp; 1173 /* 1174 * If the file wasn't claimed by devfs bind it to the normal 1175 * vnode operations here. 1176 */ 1177 if (fp->f_ops == &badfileops) { 1178 KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); 1179 fp->f_seqcount = 1; 1180 finit(fp, (flags & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, 1181 vp, &vnops); 1182 } 1183 1184 VOP_UNLOCK(vp, 0); 1185 if (flags & O_TRUNC) { 1186 error = fo_truncate(fp, 0, td->td_ucred, td); 1187 if (error) 1188 goto bad; 1189 } 1190 VFS_UNLOCK_GIANT(vfslocked); 1191 success: 1192 /* 1193 * If we haven't already installed the FD (for dupfdopen), do so now. 1194 */ 1195 if (indx == -1) { 1196 #ifdef CAPABILITIES 1197 if (nd.ni_strictrelative == 1) { 1198 /* 1199 * We are doing a strict relative lookup; wrap the 1200 * result in a capability. 1201 */ 1202 if ((error = kern_capwrap(td, fp, nd.ni_baserights, 1203 &indx)) != 0) 1204 goto bad_unlocked; 1205 } else 1206 #endif 1207 if ((error = finstall(td, fp, &indx, flags)) != 0) 1208 goto bad_unlocked; 1209 1210 } 1211 1212 /* 1213 * Release our private reference, leaving the one associated with 1214 * the descriptor table intact. 1215 */ 1216 fdrop(fp, td); 1217 td->td_retval[0] = indx; 1218 return (0); 1219 bad: 1220 VFS_UNLOCK_GIANT(vfslocked); 1221 bad_unlocked: 1222 KASSERT(indx == -1, ("indx=%d, should be -1", indx)); 1223 fdrop(fp, td); 1224 return (error); 1225 } 1226 1227 #ifdef COMPAT_43 1228 /* 1229 * Create a file. 1230 */ 1231 #ifndef _SYS_SYSPROTO_H_ 1232 struct ocreat_args { 1233 char *path; 1234 int mode; 1235 }; 1236 #endif 1237 int 1238 ocreat(td, uap) 1239 struct thread *td; 1240 register struct ocreat_args /* { 1241 char *path; 1242 int mode; 1243 } */ *uap; 1244 { 1245 1246 return (kern_open(td, uap->path, UIO_USERSPACE, 1247 O_WRONLY | O_CREAT | O_TRUNC, uap->mode)); 1248 } 1249 #endif /* COMPAT_43 */ 1250 1251 /* 1252 * Create a special file. 1253 */ 1254 #ifndef _SYS_SYSPROTO_H_ 1255 struct mknod_args { 1256 char *path; 1257 int mode; 1258 int dev; 1259 }; 1260 #endif 1261 int 1262 sys_mknod(td, uap) 1263 struct thread *td; 1264 register struct mknod_args /* { 1265 char *path; 1266 int mode; 1267 int dev; 1268 } */ *uap; 1269 { 1270 1271 return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); 1272 } 1273 1274 #ifndef _SYS_SYSPROTO_H_ 1275 struct mknodat_args { 1276 int fd; 1277 char *path; 1278 mode_t mode; 1279 dev_t dev; 1280 }; 1281 #endif 1282 int 1283 sys_mknodat(struct thread *td, struct mknodat_args *uap) 1284 { 1285 1286 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, 1287 uap->dev)); 1288 } 1289 1290 int 1291 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, 1292 int dev) 1293 { 1294 1295 return (kern_mknodat(td, AT_FDCWD, path, pathseg, mode, dev)); 1296 } 1297 1298 int 1299 kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1300 int mode, int dev) 1301 { 1302 struct vnode *vp; 1303 struct mount *mp; 1304 struct vattr vattr; 1305 int error; 1306 int whiteout = 0; 1307 struct nameidata nd; 1308 int vfslocked; 1309 1310 AUDIT_ARG_MODE(mode); 1311 AUDIT_ARG_DEV(dev); 1312 switch (mode & S_IFMT) { 1313 case S_IFCHR: 1314 case S_IFBLK: 1315 error = priv_check(td, PRIV_VFS_MKNOD_DEV); 1316 break; 1317 case S_IFMT: 1318 error = priv_check(td, PRIV_VFS_MKNOD_BAD); 1319 break; 1320 case S_IFWHT: 1321 error = priv_check(td, PRIV_VFS_MKNOD_WHT); 1322 break; 1323 case S_IFIFO: 1324 if (dev == 0) 1325 return (kern_mkfifoat(td, fd, path, pathseg, mode)); 1326 /* FALLTHROUGH */ 1327 default: 1328 error = EINVAL; 1329 break; 1330 } 1331 if (error) 1332 return (error); 1333 restart: 1334 bwillwrite(); 1335 NDINIT_ATRIGHTS(&nd, CREATE, 1336 LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, fd, 1337 CAP_MKNOD, td); 1338 if ((error = namei(&nd)) != 0) 1339 return (error); 1340 vfslocked = NDHASGIANT(&nd); 1341 vp = nd.ni_vp; 1342 if (vp != NULL) { 1343 NDFREE(&nd, NDF_ONLY_PNBUF); 1344 if (vp == nd.ni_dvp) 1345 vrele(nd.ni_dvp); 1346 else 1347 vput(nd.ni_dvp); 1348 vrele(vp); 1349 VFS_UNLOCK_GIANT(vfslocked); 1350 return (EEXIST); 1351 } else { 1352 VATTR_NULL(&vattr); 1353 vattr.va_mode = (mode & ALLPERMS) & 1354 ~td->td_proc->p_fd->fd_cmask; 1355 vattr.va_rdev = dev; 1356 whiteout = 0; 1357 1358 switch (mode & S_IFMT) { 1359 case S_IFMT: /* used by badsect to flag bad sectors */ 1360 vattr.va_type = VBAD; 1361 break; 1362 case S_IFCHR: 1363 vattr.va_type = VCHR; 1364 break; 1365 case S_IFBLK: 1366 vattr.va_type = VBLK; 1367 break; 1368 case S_IFWHT: 1369 whiteout = 1; 1370 break; 1371 default: 1372 panic("kern_mknod: invalid mode"); 1373 } 1374 } 1375 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1376 NDFREE(&nd, NDF_ONLY_PNBUF); 1377 vput(nd.ni_dvp); 1378 VFS_UNLOCK_GIANT(vfslocked); 1379 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1380 return (error); 1381 goto restart; 1382 } 1383 #ifdef MAC 1384 if (error == 0 && !whiteout) 1385 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, 1386 &nd.ni_cnd, &vattr); 1387 #endif 1388 if (!error) { 1389 if (whiteout) 1390 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1391 else { 1392 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1393 &nd.ni_cnd, &vattr); 1394 if (error == 0) 1395 vput(nd.ni_vp); 1396 } 1397 } 1398 NDFREE(&nd, NDF_ONLY_PNBUF); 1399 vput(nd.ni_dvp); 1400 vn_finished_write(mp); 1401 VFS_UNLOCK_GIANT(vfslocked); 1402 return (error); 1403 } 1404 1405 /* 1406 * Create a named pipe. 1407 */ 1408 #ifndef _SYS_SYSPROTO_H_ 1409 struct mkfifo_args { 1410 char *path; 1411 int mode; 1412 }; 1413 #endif 1414 int 1415 sys_mkfifo(td, uap) 1416 struct thread *td; 1417 register struct mkfifo_args /* { 1418 char *path; 1419 int mode; 1420 } */ *uap; 1421 { 1422 1423 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); 1424 } 1425 1426 #ifndef _SYS_SYSPROTO_H_ 1427 struct mkfifoat_args { 1428 int fd; 1429 char *path; 1430 mode_t mode; 1431 }; 1432 #endif 1433 int 1434 sys_mkfifoat(struct thread *td, struct mkfifoat_args *uap) 1435 { 1436 1437 return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE, 1438 uap->mode)); 1439 } 1440 1441 int 1442 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) 1443 { 1444 1445 return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode)); 1446 } 1447 1448 int 1449 kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1450 int mode) 1451 { 1452 struct mount *mp; 1453 struct vattr vattr; 1454 int error; 1455 struct nameidata nd; 1456 int vfslocked; 1457 1458 AUDIT_ARG_MODE(mode); 1459 restart: 1460 bwillwrite(); 1461 NDINIT_ATRIGHTS(&nd, CREATE, 1462 LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, fd, 1463 CAP_MKFIFO, td); 1464 if ((error = namei(&nd)) != 0) 1465 return (error); 1466 vfslocked = NDHASGIANT(&nd); 1467 if (nd.ni_vp != NULL) { 1468 NDFREE(&nd, NDF_ONLY_PNBUF); 1469 if (nd.ni_vp == nd.ni_dvp) 1470 vrele(nd.ni_dvp); 1471 else 1472 vput(nd.ni_dvp); 1473 vrele(nd.ni_vp); 1474 VFS_UNLOCK_GIANT(vfslocked); 1475 return (EEXIST); 1476 } 1477 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1478 NDFREE(&nd, NDF_ONLY_PNBUF); 1479 vput(nd.ni_dvp); 1480 VFS_UNLOCK_GIANT(vfslocked); 1481 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1482 return (error); 1483 goto restart; 1484 } 1485 VATTR_NULL(&vattr); 1486 vattr.va_type = VFIFO; 1487 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; 1488 #ifdef MAC 1489 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1490 &vattr); 1491 if (error) 1492 goto out; 1493 #endif 1494 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1495 if (error == 0) 1496 vput(nd.ni_vp); 1497 #ifdef MAC 1498 out: 1499 #endif 1500 vput(nd.ni_dvp); 1501 vn_finished_write(mp); 1502 VFS_UNLOCK_GIANT(vfslocked); 1503 NDFREE(&nd, NDF_ONLY_PNBUF); 1504 return (error); 1505 } 1506 1507 /* 1508 * Make a hard file link. 1509 */ 1510 #ifndef _SYS_SYSPROTO_H_ 1511 struct link_args { 1512 char *path; 1513 char *link; 1514 }; 1515 #endif 1516 int 1517 sys_link(td, uap) 1518 struct thread *td; 1519 register struct link_args /* { 1520 char *path; 1521 char *link; 1522 } */ *uap; 1523 { 1524 1525 return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); 1526 } 1527 1528 #ifndef _SYS_SYSPROTO_H_ 1529 struct linkat_args { 1530 int fd1; 1531 char *path1; 1532 int fd2; 1533 char *path2; 1534 int flag; 1535 }; 1536 #endif 1537 int 1538 sys_linkat(struct thread *td, struct linkat_args *uap) 1539 { 1540 int flag; 1541 1542 flag = uap->flag; 1543 if (flag & ~AT_SYMLINK_FOLLOW) 1544 return (EINVAL); 1545 1546 return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, 1547 UIO_USERSPACE, (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW)); 1548 } 1549 1550 int hardlink_check_uid = 0; 1551 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, 1552 &hardlink_check_uid, 0, 1553 "Unprivileged processes cannot create hard links to files owned by other " 1554 "users"); 1555 static int hardlink_check_gid = 0; 1556 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, 1557 &hardlink_check_gid, 0, 1558 "Unprivileged processes cannot create hard links to files owned by other " 1559 "groups"); 1560 1561 static int 1562 can_hardlink(struct vnode *vp, struct ucred *cred) 1563 { 1564 struct vattr va; 1565 int error; 1566 1567 if (!hardlink_check_uid && !hardlink_check_gid) 1568 return (0); 1569 1570 error = VOP_GETATTR(vp, &va, cred); 1571 if (error != 0) 1572 return (error); 1573 1574 if (hardlink_check_uid && cred->cr_uid != va.va_uid) { 1575 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1576 if (error) 1577 return (error); 1578 } 1579 1580 if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { 1581 error = priv_check_cred(cred, PRIV_VFS_LINK, 0); 1582 if (error) 1583 return (error); 1584 } 1585 1586 return (0); 1587 } 1588 1589 int 1590 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) 1591 { 1592 1593 return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW)); 1594 } 1595 1596 int 1597 kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, 1598 enum uio_seg segflg, int follow) 1599 { 1600 struct vnode *vp; 1601 struct mount *mp; 1602 struct nameidata nd; 1603 int vfslocked; 1604 int lvfslocked; 1605 int error; 1606 1607 bwillwrite(); 1608 NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, segflg, path1, 1609 fd1, td); 1610 1611 if ((error = namei(&nd)) != 0) 1612 return (error); 1613 vfslocked = NDHASGIANT(&nd); 1614 NDFREE(&nd, NDF_ONLY_PNBUF); 1615 vp = nd.ni_vp; 1616 if (vp->v_type == VDIR) { 1617 vrele(vp); 1618 VFS_UNLOCK_GIANT(vfslocked); 1619 return (EPERM); /* POSIX */ 1620 } 1621 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 1622 vrele(vp); 1623 VFS_UNLOCK_GIANT(vfslocked); 1624 return (error); 1625 } 1626 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | 1627 AUDITVNODE2, segflg, path2, fd2, CAP_CREATE, td); 1628 if ((error = namei(&nd)) == 0) { 1629 lvfslocked = NDHASGIANT(&nd); 1630 if (nd.ni_vp != NULL) { 1631 if (nd.ni_dvp == nd.ni_vp) 1632 vrele(nd.ni_dvp); 1633 else 1634 vput(nd.ni_dvp); 1635 vrele(nd.ni_vp); 1636 error = EEXIST; 1637 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) 1638 == 0) { 1639 error = can_hardlink(vp, td->td_ucred); 1640 if (error == 0) 1641 #ifdef MAC 1642 error = mac_vnode_check_link(td->td_ucred, 1643 nd.ni_dvp, vp, &nd.ni_cnd); 1644 if (error == 0) 1645 #endif 1646 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1647 VOP_UNLOCK(vp, 0); 1648 vput(nd.ni_dvp); 1649 } 1650 NDFREE(&nd, NDF_ONLY_PNBUF); 1651 VFS_UNLOCK_GIANT(lvfslocked); 1652 } 1653 vrele(vp); 1654 vn_finished_write(mp); 1655 VFS_UNLOCK_GIANT(vfslocked); 1656 return (error); 1657 } 1658 1659 /* 1660 * Make a symbolic link. 1661 */ 1662 #ifndef _SYS_SYSPROTO_H_ 1663 struct symlink_args { 1664 char *path; 1665 char *link; 1666 }; 1667 #endif 1668 int 1669 sys_symlink(td, uap) 1670 struct thread *td; 1671 register struct symlink_args /* { 1672 char *path; 1673 char *link; 1674 } */ *uap; 1675 { 1676 1677 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); 1678 } 1679 1680 #ifndef _SYS_SYSPROTO_H_ 1681 struct symlinkat_args { 1682 char *path; 1683 int fd; 1684 char *path2; 1685 }; 1686 #endif 1687 int 1688 sys_symlinkat(struct thread *td, struct symlinkat_args *uap) 1689 { 1690 1691 return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2, 1692 UIO_USERSPACE)); 1693 } 1694 1695 int 1696 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) 1697 { 1698 1699 return (kern_symlinkat(td, path, AT_FDCWD, link, segflg)); 1700 } 1701 1702 int 1703 kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, 1704 enum uio_seg segflg) 1705 { 1706 struct mount *mp; 1707 struct vattr vattr; 1708 char *syspath; 1709 int error; 1710 struct nameidata nd; 1711 int vfslocked; 1712 1713 if (segflg == UIO_SYSSPACE) { 1714 syspath = path1; 1715 } else { 1716 syspath = uma_zalloc(namei_zone, M_WAITOK); 1717 if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0) 1718 goto out; 1719 } 1720 AUDIT_ARG_TEXT(syspath); 1721 restart: 1722 bwillwrite(); 1723 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | 1724 AUDITVNODE1, segflg, path2, fd, CAP_CREATE, td); 1725 if ((error = namei(&nd)) != 0) 1726 goto out; 1727 vfslocked = NDHASGIANT(&nd); 1728 if (nd.ni_vp) { 1729 NDFREE(&nd, NDF_ONLY_PNBUF); 1730 if (nd.ni_vp == nd.ni_dvp) 1731 vrele(nd.ni_dvp); 1732 else 1733 vput(nd.ni_dvp); 1734 vrele(nd.ni_vp); 1735 VFS_UNLOCK_GIANT(vfslocked); 1736 error = EEXIST; 1737 goto out; 1738 } 1739 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1740 NDFREE(&nd, NDF_ONLY_PNBUF); 1741 vput(nd.ni_dvp); 1742 VFS_UNLOCK_GIANT(vfslocked); 1743 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1744 goto out; 1745 goto restart; 1746 } 1747 VATTR_NULL(&vattr); 1748 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; 1749 #ifdef MAC 1750 vattr.va_type = VLNK; 1751 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 1752 &vattr); 1753 if (error) 1754 goto out2; 1755 #endif 1756 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); 1757 if (error == 0) 1758 vput(nd.ni_vp); 1759 #ifdef MAC 1760 out2: 1761 #endif 1762 NDFREE(&nd, NDF_ONLY_PNBUF); 1763 vput(nd.ni_dvp); 1764 vn_finished_write(mp); 1765 VFS_UNLOCK_GIANT(vfslocked); 1766 out: 1767 if (segflg != UIO_SYSSPACE) 1768 uma_zfree(namei_zone, syspath); 1769 return (error); 1770 } 1771 1772 /* 1773 * Delete a whiteout from the filesystem. 1774 */ 1775 int 1776 sys_undelete(td, uap) 1777 struct thread *td; 1778 register struct undelete_args /* { 1779 char *path; 1780 } */ *uap; 1781 { 1782 int error; 1783 struct mount *mp; 1784 struct nameidata nd; 1785 int vfslocked; 1786 1787 restart: 1788 bwillwrite(); 1789 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1, 1790 UIO_USERSPACE, uap->path, td); 1791 error = namei(&nd); 1792 if (error) 1793 return (error); 1794 vfslocked = NDHASGIANT(&nd); 1795 1796 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1797 NDFREE(&nd, NDF_ONLY_PNBUF); 1798 if (nd.ni_vp == nd.ni_dvp) 1799 vrele(nd.ni_dvp); 1800 else 1801 vput(nd.ni_dvp); 1802 if (nd.ni_vp) 1803 vrele(nd.ni_vp); 1804 VFS_UNLOCK_GIANT(vfslocked); 1805 return (EEXIST); 1806 } 1807 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1808 NDFREE(&nd, NDF_ONLY_PNBUF); 1809 vput(nd.ni_dvp); 1810 VFS_UNLOCK_GIANT(vfslocked); 1811 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 1812 return (error); 1813 goto restart; 1814 } 1815 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); 1816 NDFREE(&nd, NDF_ONLY_PNBUF); 1817 vput(nd.ni_dvp); 1818 vn_finished_write(mp); 1819 VFS_UNLOCK_GIANT(vfslocked); 1820 return (error); 1821 } 1822 1823 /* 1824 * Delete a name from the filesystem. 1825 */ 1826 #ifndef _SYS_SYSPROTO_H_ 1827 struct unlink_args { 1828 char *path; 1829 }; 1830 #endif 1831 int 1832 sys_unlink(td, uap) 1833 struct thread *td; 1834 struct unlink_args /* { 1835 char *path; 1836 } */ *uap; 1837 { 1838 1839 return (kern_unlink(td, uap->path, UIO_USERSPACE)); 1840 } 1841 1842 #ifndef _SYS_SYSPROTO_H_ 1843 struct unlinkat_args { 1844 int fd; 1845 char *path; 1846 int flag; 1847 }; 1848 #endif 1849 int 1850 sys_unlinkat(struct thread *td, struct unlinkat_args *uap) 1851 { 1852 int flag = uap->flag; 1853 int fd = uap->fd; 1854 char *path = uap->path; 1855 1856 if (flag & ~AT_REMOVEDIR) 1857 return (EINVAL); 1858 1859 if (flag & AT_REMOVEDIR) 1860 return (kern_rmdirat(td, fd, path, UIO_USERSPACE)); 1861 else 1862 return (kern_unlinkat(td, fd, path, UIO_USERSPACE, 0)); 1863 } 1864 1865 int 1866 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) 1867 { 1868 1869 return (kern_unlinkat(td, AT_FDCWD, path, pathseg, 0)); 1870 } 1871 1872 int 1873 kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 1874 ino_t oldinum) 1875 { 1876 struct mount *mp; 1877 struct vnode *vp; 1878 int error; 1879 struct nameidata nd; 1880 struct stat sb; 1881 int vfslocked; 1882 1883 restart: 1884 bwillwrite(); 1885 NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | 1886 AUDITVNODE1, pathseg, path, fd, CAP_DELETE, td); 1887 if ((error = namei(&nd)) != 0) 1888 return (error == EINVAL ? EPERM : error); 1889 vfslocked = NDHASGIANT(&nd); 1890 vp = nd.ni_vp; 1891 if (vp->v_type == VDIR && oldinum == 0) { 1892 error = EPERM; /* POSIX */ 1893 } else if (oldinum != 0 && 1894 ((error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td)) == 0) && 1895 sb.st_ino != oldinum) { 1896 error = EIDRM; /* Identifier removed */ 1897 } else { 1898 /* 1899 * The root of a mounted filesystem cannot be deleted. 1900 * 1901 * XXX: can this only be a VDIR case? 1902 */ 1903 if (vp->v_vflag & VV_ROOT) 1904 error = EBUSY; 1905 } 1906 if (error == 0) { 1907 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 1908 NDFREE(&nd, NDF_ONLY_PNBUF); 1909 vput(nd.ni_dvp); 1910 if (vp == nd.ni_dvp) 1911 vrele(vp); 1912 else 1913 vput(vp); 1914 VFS_UNLOCK_GIANT(vfslocked); 1915 if ((error = vn_start_write(NULL, &mp, 1916 V_XSLEEP | PCATCH)) != 0) 1917 return (error); 1918 goto restart; 1919 } 1920 #ifdef MAC 1921 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 1922 &nd.ni_cnd); 1923 if (error) 1924 goto out; 1925 #endif 1926 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1927 #ifdef MAC 1928 out: 1929 #endif 1930 vn_finished_write(mp); 1931 } 1932 NDFREE(&nd, NDF_ONLY_PNBUF); 1933 vput(nd.ni_dvp); 1934 if (vp == nd.ni_dvp) 1935 vrele(vp); 1936 else 1937 vput(vp); 1938 VFS_UNLOCK_GIANT(vfslocked); 1939 return (error); 1940 } 1941 1942 /* 1943 * Reposition read/write file offset. 1944 */ 1945 #ifndef _SYS_SYSPROTO_H_ 1946 struct lseek_args { 1947 int fd; 1948 int pad; 1949 off_t offset; 1950 int whence; 1951 }; 1952 #endif 1953 int 1954 sys_lseek(td, uap) 1955 struct thread *td; 1956 register struct lseek_args /* { 1957 int fd; 1958 int pad; 1959 off_t offset; 1960 int whence; 1961 } */ *uap; 1962 { 1963 struct ucred *cred = td->td_ucred; 1964 struct file *fp; 1965 struct vnode *vp; 1966 struct vattr vattr; 1967 off_t foffset, offset, size; 1968 int error, noneg; 1969 int vfslocked; 1970 1971 AUDIT_ARG_FD(uap->fd); 1972 if ((error = fget(td, uap->fd, CAP_SEEK, &fp)) != 0) 1973 return (error); 1974 if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { 1975 fdrop(fp, td); 1976 return (ESPIPE); 1977 } 1978 vp = fp->f_vnode; 1979 foffset = foffset_lock(fp, 0); 1980 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 1981 noneg = (vp->v_type != VCHR); 1982 offset = uap->offset; 1983 switch (uap->whence) { 1984 case L_INCR: 1985 if (noneg && 1986 (foffset < 0 || 1987 (offset > 0 && foffset > OFF_MAX - offset))) { 1988 error = EOVERFLOW; 1989 break; 1990 } 1991 offset += foffset; 1992 break; 1993 case L_XTND: 1994 vn_lock(vp, LK_SHARED | LK_RETRY); 1995 error = VOP_GETATTR(vp, &vattr, cred); 1996 VOP_UNLOCK(vp, 0); 1997 if (error) 1998 break; 1999 2000 /* 2001 * If the file references a disk device, then fetch 2002 * the media size and use that to determine the ending 2003 * offset. 2004 */ 2005 if (vattr.va_size == 0 && vp->v_type == VCHR && 2006 fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0) 2007 vattr.va_size = size; 2008 if (noneg && 2009 (vattr.va_size > OFF_MAX || 2010 (offset > 0 && vattr.va_size > OFF_MAX - offset))) { 2011 error = EOVERFLOW; 2012 break; 2013 } 2014 offset += vattr.va_size; 2015 break; 2016 case L_SET: 2017 break; 2018 case SEEK_DATA: 2019 error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td); 2020 break; 2021 case SEEK_HOLE: 2022 error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td); 2023 break; 2024 default: 2025 error = EINVAL; 2026 } 2027 if (error == 0 && noneg && offset < 0) 2028 error = EINVAL; 2029 if (error != 0) 2030 goto drop; 2031 VFS_KNOTE_UNLOCKED(vp, 0); 2032 *(off_t *)(td->td_retval) = offset; 2033 drop: 2034 fdrop(fp, td); 2035 VFS_UNLOCK_GIANT(vfslocked); 2036 foffset_unlock(fp, offset, error != 0 ? FOF_NOUPDATE : 0); 2037 return (error); 2038 } 2039 2040 #if defined(COMPAT_43) 2041 /* 2042 * Reposition read/write file offset. 2043 */ 2044 #ifndef _SYS_SYSPROTO_H_ 2045 struct olseek_args { 2046 int fd; 2047 long offset; 2048 int whence; 2049 }; 2050 #endif 2051 int 2052 olseek(td, uap) 2053 struct thread *td; 2054 register struct olseek_args /* { 2055 int fd; 2056 long offset; 2057 int whence; 2058 } */ *uap; 2059 { 2060 struct lseek_args /* { 2061 int fd; 2062 int pad; 2063 off_t offset; 2064 int whence; 2065 } */ nuap; 2066 2067 nuap.fd = uap->fd; 2068 nuap.offset = uap->offset; 2069 nuap.whence = uap->whence; 2070 return (sys_lseek(td, &nuap)); 2071 } 2072 #endif /* COMPAT_43 */ 2073 2074 /* Version with the 'pad' argument */ 2075 int 2076 freebsd6_lseek(td, uap) 2077 struct thread *td; 2078 register struct freebsd6_lseek_args *uap; 2079 { 2080 struct lseek_args ouap; 2081 2082 ouap.fd = uap->fd; 2083 ouap.offset = uap->offset; 2084 ouap.whence = uap->whence; 2085 return (sys_lseek(td, &ouap)); 2086 } 2087 2088 /* 2089 * Check access permissions using passed credentials. 2090 */ 2091 static int 2092 vn_access(vp, user_flags, cred, td) 2093 struct vnode *vp; 2094 int user_flags; 2095 struct ucred *cred; 2096 struct thread *td; 2097 { 2098 int error; 2099 accmode_t accmode; 2100 2101 /* Flags == 0 means only check for existence. */ 2102 error = 0; 2103 if (user_flags) { 2104 accmode = 0; 2105 if (user_flags & R_OK) 2106 accmode |= VREAD; 2107 if (user_flags & W_OK) 2108 accmode |= VWRITE; 2109 if (user_flags & X_OK) 2110 accmode |= VEXEC; 2111 #ifdef MAC 2112 error = mac_vnode_check_access(cred, vp, accmode); 2113 if (error) 2114 return (error); 2115 #endif 2116 if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 2117 error = VOP_ACCESS(vp, accmode, cred, td); 2118 } 2119 return (error); 2120 } 2121 2122 /* 2123 * Check access permissions using "real" credentials. 2124 */ 2125 #ifndef _SYS_SYSPROTO_H_ 2126 struct access_args { 2127 char *path; 2128 int amode; 2129 }; 2130 #endif 2131 int 2132 sys_access(td, uap) 2133 struct thread *td; 2134 register struct access_args /* { 2135 char *path; 2136 int amode; 2137 } */ *uap; 2138 { 2139 2140 return (kern_access(td, uap->path, UIO_USERSPACE, uap->amode)); 2141 } 2142 2143 #ifndef _SYS_SYSPROTO_H_ 2144 struct faccessat_args { 2145 int dirfd; 2146 char *path; 2147 int amode; 2148 int flag; 2149 } 2150 #endif 2151 int 2152 sys_faccessat(struct thread *td, struct faccessat_args *uap) 2153 { 2154 2155 if (uap->flag & ~AT_EACCESS) 2156 return (EINVAL); 2157 return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, 2158 uap->amode)); 2159 } 2160 2161 int 2162 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int amode) 2163 { 2164 2165 return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, amode)); 2166 } 2167 2168 int 2169 kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2170 int flag, int amode) 2171 { 2172 struct ucred *cred, *tmpcred; 2173 struct vnode *vp; 2174 struct nameidata nd; 2175 int vfslocked; 2176 int error; 2177 2178 /* 2179 * Create and modify a temporary credential instead of one that 2180 * is potentially shared. 2181 */ 2182 if (!(flag & AT_EACCESS)) { 2183 cred = td->td_ucred; 2184 tmpcred = crdup(cred); 2185 tmpcred->cr_uid = cred->cr_ruid; 2186 tmpcred->cr_groups[0] = cred->cr_rgid; 2187 td->td_ucred = tmpcred; 2188 } else 2189 cred = tmpcred = td->td_ucred; 2190 AUDIT_ARG_VALUE(amode); 2191 NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | 2192 AUDITVNODE1, pathseg, path, fd, CAP_FSTAT, td); 2193 if ((error = namei(&nd)) != 0) 2194 goto out1; 2195 vfslocked = NDHASGIANT(&nd); 2196 vp = nd.ni_vp; 2197 2198 error = vn_access(vp, amode, tmpcred, td); 2199 NDFREE(&nd, NDF_ONLY_PNBUF); 2200 vput(vp); 2201 VFS_UNLOCK_GIANT(vfslocked); 2202 out1: 2203 if (!(flag & AT_EACCESS)) { 2204 td->td_ucred = cred; 2205 crfree(tmpcred); 2206 } 2207 return (error); 2208 } 2209 2210 /* 2211 * Check access permissions using "effective" credentials. 2212 */ 2213 #ifndef _SYS_SYSPROTO_H_ 2214 struct eaccess_args { 2215 char *path; 2216 int amode; 2217 }; 2218 #endif 2219 int 2220 sys_eaccess(td, uap) 2221 struct thread *td; 2222 register struct eaccess_args /* { 2223 char *path; 2224 int amode; 2225 } */ *uap; 2226 { 2227 2228 return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->amode)); 2229 } 2230 2231 int 2232 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int amode) 2233 { 2234 2235 return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, amode)); 2236 } 2237 2238 #if defined(COMPAT_43) 2239 /* 2240 * Get file status; this version follows links. 2241 */ 2242 #ifndef _SYS_SYSPROTO_H_ 2243 struct ostat_args { 2244 char *path; 2245 struct ostat *ub; 2246 }; 2247 #endif 2248 int 2249 ostat(td, uap) 2250 struct thread *td; 2251 register struct ostat_args /* { 2252 char *path; 2253 struct ostat *ub; 2254 } */ *uap; 2255 { 2256 struct stat sb; 2257 struct ostat osb; 2258 int error; 2259 2260 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2261 if (error) 2262 return (error); 2263 cvtstat(&sb, &osb); 2264 error = copyout(&osb, uap->ub, sizeof (osb)); 2265 return (error); 2266 } 2267 2268 /* 2269 * Get file status; this version does not follow links. 2270 */ 2271 #ifndef _SYS_SYSPROTO_H_ 2272 struct olstat_args { 2273 char *path; 2274 struct ostat *ub; 2275 }; 2276 #endif 2277 int 2278 olstat(td, uap) 2279 struct thread *td; 2280 register struct olstat_args /* { 2281 char *path; 2282 struct ostat *ub; 2283 } */ *uap; 2284 { 2285 struct stat sb; 2286 struct ostat osb; 2287 int error; 2288 2289 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2290 if (error) 2291 return (error); 2292 cvtstat(&sb, &osb); 2293 error = copyout(&osb, uap->ub, sizeof (osb)); 2294 return (error); 2295 } 2296 2297 /* 2298 * Convert from an old to a new stat structure. 2299 */ 2300 void 2301 cvtstat(st, ost) 2302 struct stat *st; 2303 struct ostat *ost; 2304 { 2305 2306 ost->st_dev = st->st_dev; 2307 ost->st_ino = st->st_ino; 2308 ost->st_mode = st->st_mode; 2309 ost->st_nlink = st->st_nlink; 2310 ost->st_uid = st->st_uid; 2311 ost->st_gid = st->st_gid; 2312 ost->st_rdev = st->st_rdev; 2313 if (st->st_size < (quad_t)1 << 32) 2314 ost->st_size = st->st_size; 2315 else 2316 ost->st_size = -2; 2317 ost->st_atim = st->st_atim; 2318 ost->st_mtim = st->st_mtim; 2319 ost->st_ctim = st->st_ctim; 2320 ost->st_blksize = st->st_blksize; 2321 ost->st_blocks = st->st_blocks; 2322 ost->st_flags = st->st_flags; 2323 ost->st_gen = st->st_gen; 2324 } 2325 #endif /* COMPAT_43 */ 2326 2327 /* 2328 * Get file status; this version follows links. 2329 */ 2330 #ifndef _SYS_SYSPROTO_H_ 2331 struct stat_args { 2332 char *path; 2333 struct stat *ub; 2334 }; 2335 #endif 2336 int 2337 sys_stat(td, uap) 2338 struct thread *td; 2339 register struct stat_args /* { 2340 char *path; 2341 struct stat *ub; 2342 } */ *uap; 2343 { 2344 struct stat sb; 2345 int error; 2346 2347 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2348 if (error == 0) 2349 error = copyout(&sb, uap->ub, sizeof (sb)); 2350 return (error); 2351 } 2352 2353 #ifndef _SYS_SYSPROTO_H_ 2354 struct fstatat_args { 2355 int fd; 2356 char *path; 2357 struct stat *buf; 2358 int flag; 2359 } 2360 #endif 2361 int 2362 sys_fstatat(struct thread *td, struct fstatat_args *uap) 2363 { 2364 struct stat sb; 2365 int error; 2366 2367 error = kern_statat(td, uap->flag, uap->fd, uap->path, 2368 UIO_USERSPACE, &sb); 2369 if (error == 0) 2370 error = copyout(&sb, uap->buf, sizeof (sb)); 2371 return (error); 2372 } 2373 2374 int 2375 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2376 { 2377 2378 return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); 2379 } 2380 2381 int 2382 kern_statat(struct thread *td, int flag, int fd, char *path, 2383 enum uio_seg pathseg, struct stat *sbp) 2384 { 2385 2386 return (kern_statat_vnhook(td, flag, fd, path, pathseg, sbp, NULL)); 2387 } 2388 2389 int 2390 kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, 2391 enum uio_seg pathseg, struct stat *sbp, 2392 void (*hook)(struct vnode *vp, struct stat *sbp)) 2393 { 2394 struct nameidata nd; 2395 struct stat sb; 2396 int error, vfslocked; 2397 2398 if (flag & ~AT_SYMLINK_NOFOLLOW) 2399 return (EINVAL); 2400 2401 NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : 2402 FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, 2403 path, fd, CAP_FSTAT, td); 2404 2405 if ((error = namei(&nd)) != 0) 2406 return (error); 2407 vfslocked = NDHASGIANT(&nd); 2408 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 2409 if (!error) { 2410 SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); 2411 if (S_ISREG(sb.st_mode)) 2412 SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); 2413 if (__predict_false(hook != NULL)) 2414 hook(nd.ni_vp, &sb); 2415 } 2416 NDFREE(&nd, NDF_ONLY_PNBUF); 2417 vput(nd.ni_vp); 2418 VFS_UNLOCK_GIANT(vfslocked); 2419 if (error) 2420 return (error); 2421 *sbp = sb; 2422 #ifdef KTRACE 2423 if (KTRPOINT(td, KTR_STRUCT)) 2424 ktrstat(&sb); 2425 #endif 2426 return (0); 2427 } 2428 2429 /* 2430 * Get file status; this version does not follow links. 2431 */ 2432 #ifndef _SYS_SYSPROTO_H_ 2433 struct lstat_args { 2434 char *path; 2435 struct stat *ub; 2436 }; 2437 #endif 2438 int 2439 sys_lstat(td, uap) 2440 struct thread *td; 2441 register struct lstat_args /* { 2442 char *path; 2443 struct stat *ub; 2444 } */ *uap; 2445 { 2446 struct stat sb; 2447 int error; 2448 2449 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2450 if (error == 0) 2451 error = copyout(&sb, uap->ub, sizeof (sb)); 2452 return (error); 2453 } 2454 2455 int 2456 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) 2457 { 2458 2459 return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, 2460 sbp)); 2461 } 2462 2463 /* 2464 * Implementation of the NetBSD [l]stat() functions. 2465 */ 2466 void 2467 cvtnstat(sb, nsb) 2468 struct stat *sb; 2469 struct nstat *nsb; 2470 { 2471 bzero(nsb, sizeof *nsb); 2472 nsb->st_dev = sb->st_dev; 2473 nsb->st_ino = sb->st_ino; 2474 nsb->st_mode = sb->st_mode; 2475 nsb->st_nlink = sb->st_nlink; 2476 nsb->st_uid = sb->st_uid; 2477 nsb->st_gid = sb->st_gid; 2478 nsb->st_rdev = sb->st_rdev; 2479 nsb->st_atim = sb->st_atim; 2480 nsb->st_mtim = sb->st_mtim; 2481 nsb->st_ctim = sb->st_ctim; 2482 nsb->st_size = sb->st_size; 2483 nsb->st_blocks = sb->st_blocks; 2484 nsb->st_blksize = sb->st_blksize; 2485 nsb->st_flags = sb->st_flags; 2486 nsb->st_gen = sb->st_gen; 2487 nsb->st_birthtim = sb->st_birthtim; 2488 } 2489 2490 #ifndef _SYS_SYSPROTO_H_ 2491 struct nstat_args { 2492 char *path; 2493 struct nstat *ub; 2494 }; 2495 #endif 2496 int 2497 sys_nstat(td, uap) 2498 struct thread *td; 2499 register struct nstat_args /* { 2500 char *path; 2501 struct nstat *ub; 2502 } */ *uap; 2503 { 2504 struct stat sb; 2505 struct nstat nsb; 2506 int error; 2507 2508 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2509 if (error) 2510 return (error); 2511 cvtnstat(&sb, &nsb); 2512 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2513 return (error); 2514 } 2515 2516 /* 2517 * NetBSD lstat. Get file status; this version does not follow links. 2518 */ 2519 #ifndef _SYS_SYSPROTO_H_ 2520 struct lstat_args { 2521 char *path; 2522 struct stat *ub; 2523 }; 2524 #endif 2525 int 2526 sys_nlstat(td, uap) 2527 struct thread *td; 2528 register struct nlstat_args /* { 2529 char *path; 2530 struct nstat *ub; 2531 } */ *uap; 2532 { 2533 struct stat sb; 2534 struct nstat nsb; 2535 int error; 2536 2537 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2538 if (error) 2539 return (error); 2540 cvtnstat(&sb, &nsb); 2541 error = copyout(&nsb, uap->ub, sizeof (nsb)); 2542 return (error); 2543 } 2544 2545 /* 2546 * Get configurable pathname variables. 2547 */ 2548 #ifndef _SYS_SYSPROTO_H_ 2549 struct pathconf_args { 2550 char *path; 2551 int name; 2552 }; 2553 #endif 2554 int 2555 sys_pathconf(td, uap) 2556 struct thread *td; 2557 register struct pathconf_args /* { 2558 char *path; 2559 int name; 2560 } */ *uap; 2561 { 2562 2563 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, FOLLOW)); 2564 } 2565 2566 #ifndef _SYS_SYSPROTO_H_ 2567 struct lpathconf_args { 2568 char *path; 2569 int name; 2570 }; 2571 #endif 2572 int 2573 sys_lpathconf(td, uap) 2574 struct thread *td; 2575 register struct lpathconf_args /* { 2576 char *path; 2577 int name; 2578 } */ *uap; 2579 { 2580 2581 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, NOFOLLOW)); 2582 } 2583 2584 int 2585 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name, 2586 u_long flags) 2587 { 2588 struct nameidata nd; 2589 int error, vfslocked; 2590 2591 NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1 | 2592 flags, pathseg, path, td); 2593 if ((error = namei(&nd)) != 0) 2594 return (error); 2595 vfslocked = NDHASGIANT(&nd); 2596 NDFREE(&nd, NDF_ONLY_PNBUF); 2597 2598 /* If asynchronous I/O is available, it works for all files. */ 2599 if (name == _PC_ASYNC_IO) 2600 td->td_retval[0] = async_io_version; 2601 else 2602 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval); 2603 vput(nd.ni_vp); 2604 VFS_UNLOCK_GIANT(vfslocked); 2605 return (error); 2606 } 2607 2608 /* 2609 * Return target name of a symbolic link. 2610 */ 2611 #ifndef _SYS_SYSPROTO_H_ 2612 struct readlink_args { 2613 char *path; 2614 char *buf; 2615 size_t count; 2616 }; 2617 #endif 2618 int 2619 sys_readlink(td, uap) 2620 struct thread *td; 2621 register struct readlink_args /* { 2622 char *path; 2623 char *buf; 2624 size_t count; 2625 } */ *uap; 2626 { 2627 2628 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, 2629 UIO_USERSPACE, uap->count)); 2630 } 2631 #ifndef _SYS_SYSPROTO_H_ 2632 struct readlinkat_args { 2633 int fd; 2634 char *path; 2635 char *buf; 2636 size_t bufsize; 2637 }; 2638 #endif 2639 int 2640 sys_readlinkat(struct thread *td, struct readlinkat_args *uap) 2641 { 2642 2643 return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, 2644 uap->buf, UIO_USERSPACE, uap->bufsize)); 2645 } 2646 2647 int 2648 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, 2649 enum uio_seg bufseg, size_t count) 2650 { 2651 2652 return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, 2653 count)); 2654 } 2655 2656 int 2657 kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2658 char *buf, enum uio_seg bufseg, size_t count) 2659 { 2660 struct vnode *vp; 2661 struct iovec aiov; 2662 struct uio auio; 2663 int error; 2664 struct nameidata nd; 2665 int vfslocked; 2666 2667 if (count > IOSIZE_MAX) 2668 return (EINVAL); 2669 2670 NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | 2671 AUDITVNODE1, pathseg, path, fd, td); 2672 2673 if ((error = namei(&nd)) != 0) 2674 return (error); 2675 NDFREE(&nd, NDF_ONLY_PNBUF); 2676 vfslocked = NDHASGIANT(&nd); 2677 vp = nd.ni_vp; 2678 #ifdef MAC 2679 error = mac_vnode_check_readlink(td->td_ucred, vp); 2680 if (error) { 2681 vput(vp); 2682 VFS_UNLOCK_GIANT(vfslocked); 2683 return (error); 2684 } 2685 #endif 2686 if (vp->v_type != VLNK) 2687 error = EINVAL; 2688 else { 2689 aiov.iov_base = buf; 2690 aiov.iov_len = count; 2691 auio.uio_iov = &aiov; 2692 auio.uio_iovcnt = 1; 2693 auio.uio_offset = 0; 2694 auio.uio_rw = UIO_READ; 2695 auio.uio_segflg = bufseg; 2696 auio.uio_td = td; 2697 auio.uio_resid = count; 2698 error = VOP_READLINK(vp, &auio, td->td_ucred); 2699 } 2700 vput(vp); 2701 VFS_UNLOCK_GIANT(vfslocked); 2702 td->td_retval[0] = count - auio.uio_resid; 2703 return (error); 2704 } 2705 2706 /* 2707 * Common implementation code for chflags() and fchflags(). 2708 */ 2709 static int 2710 setfflags(td, vp, flags) 2711 struct thread *td; 2712 struct vnode *vp; 2713 int flags; 2714 { 2715 int error; 2716 struct mount *mp; 2717 struct vattr vattr; 2718 2719 /* We can't support the value matching VNOVAL. */ 2720 if (flags == VNOVAL) 2721 return (EOPNOTSUPP); 2722 2723 /* 2724 * Prevent non-root users from setting flags on devices. When 2725 * a device is reused, users can retain ownership of the device 2726 * if they are allowed to set flags and programs assume that 2727 * chown can't fail when done as root. 2728 */ 2729 if (vp->v_type == VCHR || vp->v_type == VBLK) { 2730 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); 2731 if (error) 2732 return (error); 2733 } 2734 2735 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2736 return (error); 2737 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2738 VATTR_NULL(&vattr); 2739 vattr.va_flags = flags; 2740 #ifdef MAC 2741 error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); 2742 if (error == 0) 2743 #endif 2744 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 2745 VOP_UNLOCK(vp, 0); 2746 vn_finished_write(mp); 2747 return (error); 2748 } 2749 2750 /* 2751 * Change flags of a file given a path name. 2752 */ 2753 #ifndef _SYS_SYSPROTO_H_ 2754 struct chflags_args { 2755 char *path; 2756 int flags; 2757 }; 2758 #endif 2759 int 2760 sys_chflags(td, uap) 2761 struct thread *td; 2762 register struct chflags_args /* { 2763 char *path; 2764 int flags; 2765 } */ *uap; 2766 { 2767 int error; 2768 struct nameidata nd; 2769 int vfslocked; 2770 2771 AUDIT_ARG_FFLAGS(uap->flags); 2772 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2773 uap->path, td); 2774 if ((error = namei(&nd)) != 0) 2775 return (error); 2776 NDFREE(&nd, NDF_ONLY_PNBUF); 2777 vfslocked = NDHASGIANT(&nd); 2778 error = setfflags(td, nd.ni_vp, uap->flags); 2779 vrele(nd.ni_vp); 2780 VFS_UNLOCK_GIANT(vfslocked); 2781 return (error); 2782 } 2783 2784 /* 2785 * Same as chflags() but doesn't follow symlinks. 2786 */ 2787 int 2788 sys_lchflags(td, uap) 2789 struct thread *td; 2790 register struct lchflags_args /* { 2791 char *path; 2792 int flags; 2793 } */ *uap; 2794 { 2795 int error; 2796 struct nameidata nd; 2797 int vfslocked; 2798 2799 AUDIT_ARG_FFLAGS(uap->flags); 2800 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, 2801 uap->path, td); 2802 if ((error = namei(&nd)) != 0) 2803 return (error); 2804 vfslocked = NDHASGIANT(&nd); 2805 NDFREE(&nd, NDF_ONLY_PNBUF); 2806 error = setfflags(td, nd.ni_vp, uap->flags); 2807 vrele(nd.ni_vp); 2808 VFS_UNLOCK_GIANT(vfslocked); 2809 return (error); 2810 } 2811 2812 /* 2813 * Change flags of a file given a file descriptor. 2814 */ 2815 #ifndef _SYS_SYSPROTO_H_ 2816 struct fchflags_args { 2817 int fd; 2818 int flags; 2819 }; 2820 #endif 2821 int 2822 sys_fchflags(td, uap) 2823 struct thread *td; 2824 register struct fchflags_args /* { 2825 int fd; 2826 int flags; 2827 } */ *uap; 2828 { 2829 struct file *fp; 2830 int vfslocked; 2831 int error; 2832 2833 AUDIT_ARG_FD(uap->fd); 2834 AUDIT_ARG_FFLAGS(uap->flags); 2835 if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHFLAGS, 2836 &fp)) != 0) 2837 return (error); 2838 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 2839 #ifdef AUDIT 2840 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 2841 AUDIT_ARG_VNODE1(fp->f_vnode); 2842 VOP_UNLOCK(fp->f_vnode, 0); 2843 #endif 2844 error = setfflags(td, fp->f_vnode, uap->flags); 2845 VFS_UNLOCK_GIANT(vfslocked); 2846 fdrop(fp, td); 2847 return (error); 2848 } 2849 2850 /* 2851 * Common implementation code for chmod(), lchmod() and fchmod(). 2852 */ 2853 int 2854 setfmode(td, cred, vp, mode) 2855 struct thread *td; 2856 struct ucred *cred; 2857 struct vnode *vp; 2858 int mode; 2859 { 2860 int error; 2861 struct mount *mp; 2862 struct vattr vattr; 2863 2864 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 2865 return (error); 2866 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2867 VATTR_NULL(&vattr); 2868 vattr.va_mode = mode & ALLPERMS; 2869 #ifdef MAC 2870 error = mac_vnode_check_setmode(cred, vp, vattr.va_mode); 2871 if (error == 0) 2872 #endif 2873 error = VOP_SETATTR(vp, &vattr, cred); 2874 VOP_UNLOCK(vp, 0); 2875 vn_finished_write(mp); 2876 return (error); 2877 } 2878 2879 /* 2880 * Change mode of a file given path name. 2881 */ 2882 #ifndef _SYS_SYSPROTO_H_ 2883 struct chmod_args { 2884 char *path; 2885 int mode; 2886 }; 2887 #endif 2888 int 2889 sys_chmod(td, uap) 2890 struct thread *td; 2891 register struct chmod_args /* { 2892 char *path; 2893 int mode; 2894 } */ *uap; 2895 { 2896 2897 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); 2898 } 2899 2900 #ifndef _SYS_SYSPROTO_H_ 2901 struct fchmodat_args { 2902 int dirfd; 2903 char *path; 2904 mode_t mode; 2905 int flag; 2906 } 2907 #endif 2908 int 2909 sys_fchmodat(struct thread *td, struct fchmodat_args *uap) 2910 { 2911 int flag = uap->flag; 2912 int fd = uap->fd; 2913 char *path = uap->path; 2914 mode_t mode = uap->mode; 2915 2916 if (flag & ~AT_SYMLINK_NOFOLLOW) 2917 return (EINVAL); 2918 2919 return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); 2920 } 2921 2922 int 2923 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) 2924 { 2925 2926 return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); 2927 } 2928 2929 /* 2930 * Change mode of a file given path name (don't follow links.) 2931 */ 2932 #ifndef _SYS_SYSPROTO_H_ 2933 struct lchmod_args { 2934 char *path; 2935 int mode; 2936 }; 2937 #endif 2938 int 2939 sys_lchmod(td, uap) 2940 struct thread *td; 2941 register struct lchmod_args /* { 2942 char *path; 2943 int mode; 2944 } */ *uap; 2945 { 2946 2947 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 2948 uap->mode, AT_SYMLINK_NOFOLLOW)); 2949 } 2950 2951 2952 int 2953 kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 2954 mode_t mode, int flag) 2955 { 2956 int error; 2957 struct nameidata nd; 2958 int vfslocked; 2959 int follow; 2960 2961 AUDIT_ARG_MODE(mode); 2962 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 2963 NDINIT_ATRIGHTS(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, 2964 path, fd, CAP_FCHMOD, td); 2965 if ((error = namei(&nd)) != 0) 2966 return (error); 2967 vfslocked = NDHASGIANT(&nd); 2968 NDFREE(&nd, NDF_ONLY_PNBUF); 2969 error = setfmode(td, td->td_ucred, nd.ni_vp, mode); 2970 vrele(nd.ni_vp); 2971 VFS_UNLOCK_GIANT(vfslocked); 2972 return (error); 2973 } 2974 2975 /* 2976 * Change mode of a file given a file descriptor. 2977 */ 2978 #ifndef _SYS_SYSPROTO_H_ 2979 struct fchmod_args { 2980 int fd; 2981 int mode; 2982 }; 2983 #endif 2984 int 2985 sys_fchmod(struct thread *td, struct fchmod_args *uap) 2986 { 2987 struct file *fp; 2988 int error; 2989 2990 AUDIT_ARG_FD(uap->fd); 2991 AUDIT_ARG_MODE(uap->mode); 2992 2993 error = fget(td, uap->fd, CAP_FCHMOD, &fp); 2994 if (error != 0) 2995 return (error); 2996 error = fo_chmod(fp, uap->mode, td->td_ucred, td); 2997 fdrop(fp, td); 2998 return (error); 2999 } 3000 3001 /* 3002 * Common implementation for chown(), lchown(), and fchown() 3003 */ 3004 int 3005 setfown(td, cred, vp, uid, gid) 3006 struct thread *td; 3007 struct ucred *cred; 3008 struct vnode *vp; 3009 uid_t uid; 3010 gid_t gid; 3011 { 3012 int error; 3013 struct mount *mp; 3014 struct vattr vattr; 3015 3016 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3017 return (error); 3018 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3019 VATTR_NULL(&vattr); 3020 vattr.va_uid = uid; 3021 vattr.va_gid = gid; 3022 #ifdef MAC 3023 error = mac_vnode_check_setowner(cred, vp, vattr.va_uid, 3024 vattr.va_gid); 3025 if (error == 0) 3026 #endif 3027 error = VOP_SETATTR(vp, &vattr, cred); 3028 VOP_UNLOCK(vp, 0); 3029 vn_finished_write(mp); 3030 return (error); 3031 } 3032 3033 /* 3034 * Set ownership given a path name. 3035 */ 3036 #ifndef _SYS_SYSPROTO_H_ 3037 struct chown_args { 3038 char *path; 3039 int uid; 3040 int gid; 3041 }; 3042 #endif 3043 int 3044 sys_chown(td, uap) 3045 struct thread *td; 3046 register struct chown_args /* { 3047 char *path; 3048 int uid; 3049 int gid; 3050 } */ *uap; 3051 { 3052 3053 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 3054 } 3055 3056 #ifndef _SYS_SYSPROTO_H_ 3057 struct fchownat_args { 3058 int fd; 3059 const char * path; 3060 uid_t uid; 3061 gid_t gid; 3062 int flag; 3063 }; 3064 #endif 3065 int 3066 sys_fchownat(struct thread *td, struct fchownat_args *uap) 3067 { 3068 int flag; 3069 3070 flag = uap->flag; 3071 if (flag & ~AT_SYMLINK_NOFOLLOW) 3072 return (EINVAL); 3073 3074 return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, 3075 uap->gid, uap->flag)); 3076 } 3077 3078 int 3079 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3080 int gid) 3081 { 3082 3083 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); 3084 } 3085 3086 int 3087 kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3088 int uid, int gid, int flag) 3089 { 3090 struct nameidata nd; 3091 int error, vfslocked, follow; 3092 3093 AUDIT_ARG_OWNER(uid, gid); 3094 follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 3095 NDINIT_ATRIGHTS(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, 3096 path, fd, CAP_FCHOWN, td); 3097 3098 if ((error = namei(&nd)) != 0) 3099 return (error); 3100 vfslocked = NDHASGIANT(&nd); 3101 NDFREE(&nd, NDF_ONLY_PNBUF); 3102 error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid); 3103 vrele(nd.ni_vp); 3104 VFS_UNLOCK_GIANT(vfslocked); 3105 return (error); 3106 } 3107 3108 /* 3109 * Set ownership given a path name, do not cross symlinks. 3110 */ 3111 #ifndef _SYS_SYSPROTO_H_ 3112 struct lchown_args { 3113 char *path; 3114 int uid; 3115 int gid; 3116 }; 3117 #endif 3118 int 3119 sys_lchown(td, uap) 3120 struct thread *td; 3121 register struct lchown_args /* { 3122 char *path; 3123 int uid; 3124 int gid; 3125 } */ *uap; 3126 { 3127 3128 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); 3129 } 3130 3131 int 3132 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, 3133 int gid) 3134 { 3135 3136 return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 3137 AT_SYMLINK_NOFOLLOW)); 3138 } 3139 3140 /* 3141 * Set ownership given a file descriptor. 3142 */ 3143 #ifndef _SYS_SYSPROTO_H_ 3144 struct fchown_args { 3145 int fd; 3146 int uid; 3147 int gid; 3148 }; 3149 #endif 3150 int 3151 sys_fchown(td, uap) 3152 struct thread *td; 3153 register struct fchown_args /* { 3154 int fd; 3155 int uid; 3156 int gid; 3157 } */ *uap; 3158 { 3159 struct file *fp; 3160 int error; 3161 3162 AUDIT_ARG_FD(uap->fd); 3163 AUDIT_ARG_OWNER(uap->uid, uap->gid); 3164 error = fget(td, uap->fd, CAP_FCHOWN, &fp); 3165 if (error != 0) 3166 return (error); 3167 error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td); 3168 fdrop(fp, td); 3169 return (error); 3170 } 3171 3172 /* 3173 * Common implementation code for utimes(), lutimes(), and futimes(). 3174 */ 3175 static int 3176 getutimes(usrtvp, tvpseg, tsp) 3177 const struct timeval *usrtvp; 3178 enum uio_seg tvpseg; 3179 struct timespec *tsp; 3180 { 3181 struct timeval tv[2]; 3182 const struct timeval *tvp; 3183 int error; 3184 3185 if (usrtvp == NULL) { 3186 vfs_timestamp(&tsp[0]); 3187 tsp[1] = tsp[0]; 3188 } else { 3189 if (tvpseg == UIO_SYSSPACE) { 3190 tvp = usrtvp; 3191 } else { 3192 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) 3193 return (error); 3194 tvp = tv; 3195 } 3196 3197 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || 3198 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) 3199 return (EINVAL); 3200 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); 3201 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); 3202 } 3203 return (0); 3204 } 3205 3206 /* 3207 * Common implementation code for utimes(), lutimes(), and futimes(). 3208 */ 3209 static int 3210 setutimes(td, vp, ts, numtimes, nullflag) 3211 struct thread *td; 3212 struct vnode *vp; 3213 const struct timespec *ts; 3214 int numtimes; 3215 int nullflag; 3216 { 3217 int error, setbirthtime; 3218 struct mount *mp; 3219 struct vattr vattr; 3220 3221 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3222 return (error); 3223 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3224 setbirthtime = 0; 3225 if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && 3226 timespeccmp(&ts[1], &vattr.va_birthtime, < )) 3227 setbirthtime = 1; 3228 VATTR_NULL(&vattr); 3229 vattr.va_atime = ts[0]; 3230 vattr.va_mtime = ts[1]; 3231 if (setbirthtime) 3232 vattr.va_birthtime = ts[1]; 3233 if (numtimes > 2) 3234 vattr.va_birthtime = ts[2]; 3235 if (nullflag) 3236 vattr.va_vaflags |= VA_UTIMES_NULL; 3237 #ifdef MAC 3238 error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, 3239 vattr.va_mtime); 3240 #endif 3241 if (error == 0) 3242 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3243 VOP_UNLOCK(vp, 0); 3244 vn_finished_write(mp); 3245 return (error); 3246 } 3247 3248 /* 3249 * Set the access and modification times of a file. 3250 */ 3251 #ifndef _SYS_SYSPROTO_H_ 3252 struct utimes_args { 3253 char *path; 3254 struct timeval *tptr; 3255 }; 3256 #endif 3257 int 3258 sys_utimes(td, uap) 3259 struct thread *td; 3260 register struct utimes_args /* { 3261 char *path; 3262 struct timeval *tptr; 3263 } */ *uap; 3264 { 3265 3266 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3267 UIO_USERSPACE)); 3268 } 3269 3270 #ifndef _SYS_SYSPROTO_H_ 3271 struct futimesat_args { 3272 int fd; 3273 const char * path; 3274 const struct timeval * times; 3275 }; 3276 #endif 3277 int 3278 sys_futimesat(struct thread *td, struct futimesat_args *uap) 3279 { 3280 3281 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 3282 uap->times, UIO_USERSPACE)); 3283 } 3284 3285 int 3286 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, 3287 struct timeval *tptr, enum uio_seg tptrseg) 3288 { 3289 3290 return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); 3291 } 3292 3293 int 3294 kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, 3295 struct timeval *tptr, enum uio_seg tptrseg) 3296 { 3297 struct nameidata nd; 3298 struct timespec ts[2]; 3299 int error, vfslocked; 3300 3301 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3302 return (error); 3303 NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, 3304 path, fd, CAP_FUTIMES, td); 3305 3306 if ((error = namei(&nd)) != 0) 3307 return (error); 3308 vfslocked = NDHASGIANT(&nd); 3309 NDFREE(&nd, NDF_ONLY_PNBUF); 3310 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3311 vrele(nd.ni_vp); 3312 VFS_UNLOCK_GIANT(vfslocked); 3313 return (error); 3314 } 3315 3316 /* 3317 * Set the access and modification times of a file. 3318 */ 3319 #ifndef _SYS_SYSPROTO_H_ 3320 struct lutimes_args { 3321 char *path; 3322 struct timeval *tptr; 3323 }; 3324 #endif 3325 int 3326 sys_lutimes(td, uap) 3327 struct thread *td; 3328 register struct lutimes_args /* { 3329 char *path; 3330 struct timeval *tptr; 3331 } */ *uap; 3332 { 3333 3334 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, 3335 UIO_USERSPACE)); 3336 } 3337 3338 int 3339 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, 3340 struct timeval *tptr, enum uio_seg tptrseg) 3341 { 3342 struct timespec ts[2]; 3343 int error; 3344 struct nameidata nd; 3345 int vfslocked; 3346 3347 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3348 return (error); 3349 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3350 if ((error = namei(&nd)) != 0) 3351 return (error); 3352 vfslocked = NDHASGIANT(&nd); 3353 NDFREE(&nd, NDF_ONLY_PNBUF); 3354 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); 3355 vrele(nd.ni_vp); 3356 VFS_UNLOCK_GIANT(vfslocked); 3357 return (error); 3358 } 3359 3360 /* 3361 * Set the access and modification times of a file. 3362 */ 3363 #ifndef _SYS_SYSPROTO_H_ 3364 struct futimes_args { 3365 int fd; 3366 struct timeval *tptr; 3367 }; 3368 #endif 3369 int 3370 sys_futimes(td, uap) 3371 struct thread *td; 3372 register struct futimes_args /* { 3373 int fd; 3374 struct timeval *tptr; 3375 } */ *uap; 3376 { 3377 3378 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); 3379 } 3380 3381 int 3382 kern_futimes(struct thread *td, int fd, struct timeval *tptr, 3383 enum uio_seg tptrseg) 3384 { 3385 struct timespec ts[2]; 3386 struct file *fp; 3387 int vfslocked; 3388 int error; 3389 3390 AUDIT_ARG_FD(fd); 3391 if ((error = getutimes(tptr, tptrseg, ts)) != 0) 3392 return (error); 3393 if ((error = getvnode(td->td_proc->p_fd, fd, CAP_FUTIMES, &fp)) 3394 != 0) 3395 return (error); 3396 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); 3397 #ifdef AUDIT 3398 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); 3399 AUDIT_ARG_VNODE1(fp->f_vnode); 3400 VOP_UNLOCK(fp->f_vnode, 0); 3401 #endif 3402 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); 3403 VFS_UNLOCK_GIANT(vfslocked); 3404 fdrop(fp, td); 3405 return (error); 3406 } 3407 3408 /* 3409 * Truncate a file given its path name. 3410 */ 3411 #ifndef _SYS_SYSPROTO_H_ 3412 struct truncate_args { 3413 char *path; 3414 int pad; 3415 off_t length; 3416 }; 3417 #endif 3418 int 3419 sys_truncate(td, uap) 3420 struct thread *td; 3421 register struct truncate_args /* { 3422 char *path; 3423 int pad; 3424 off_t length; 3425 } */ *uap; 3426 { 3427 3428 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); 3429 } 3430 3431 int 3432 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) 3433 { 3434 struct mount *mp; 3435 struct vnode *vp; 3436 struct vattr vattr; 3437 int error; 3438 struct nameidata nd; 3439 int vfslocked; 3440 3441 if (length < 0) 3442 return(EINVAL); 3443 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); 3444 if ((error = namei(&nd)) != 0) 3445 return (error); 3446 vfslocked = NDHASGIANT(&nd); 3447 vp = nd.ni_vp; 3448 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { 3449 vrele(vp); 3450 VFS_UNLOCK_GIANT(vfslocked); 3451 return (error); 3452 } 3453 NDFREE(&nd, NDF_ONLY_PNBUF); 3454 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 3455 if (vp->v_type == VDIR) 3456 error = EISDIR; 3457 #ifdef MAC 3458 else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { 3459 } 3460 #endif 3461 else if ((error = vn_writechk(vp)) == 0 && 3462 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { 3463 VATTR_NULL(&vattr); 3464 vattr.va_size = length; 3465 error = VOP_SETATTR(vp, &vattr, td->td_ucred); 3466 } 3467 vput(vp); 3468 vn_finished_write(mp); 3469 VFS_UNLOCK_GIANT(vfslocked); 3470 return (error); 3471 } 3472 3473 #if defined(COMPAT_43) 3474 /* 3475 * Truncate a file given its path name. 3476 */ 3477 #ifndef _SYS_SYSPROTO_H_ 3478 struct otruncate_args { 3479 char *path; 3480 long length; 3481 }; 3482 #endif 3483 int 3484 otruncate(td, uap) 3485 struct thread *td; 3486 register struct otruncate_args /* { 3487 char *path; 3488 long length; 3489 } */ *uap; 3490 { 3491 struct truncate_args /* { 3492 char *path; 3493 int pad; 3494 off_t length; 3495 } */ nuap; 3496 3497 nuap.path = uap->path; 3498 nuap.length = uap->length; 3499 return (sys_truncate(td, &nuap)); 3500 } 3501 #endif /* COMPAT_43 */ 3502 3503 /* Versions with the pad argument */ 3504 int 3505 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) 3506 { 3507 struct truncate_args ouap; 3508 3509 ouap.path = uap->path; 3510 ouap.length = uap->length; 3511 return (sys_truncate(td, &ouap)); 3512 } 3513 3514 int 3515 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) 3516 { 3517 struct ftruncate_args ouap; 3518 3519 ouap.fd = uap->fd; 3520 ouap.length = uap->length; 3521 return (sys_ftruncate(td, &ouap)); 3522 } 3523 3524 /* 3525 * Sync an open file. 3526 */ 3527 #ifndef _SYS_SYSPROTO_H_ 3528 struct fsync_args { 3529 int fd; 3530 }; 3531 #endif 3532 int 3533 sys_fsync(td, uap) 3534 struct thread *td; 3535 struct fsync_args /* { 3536 int fd; 3537 } */ *uap; 3538 { 3539 struct vnode *vp; 3540 struct mount *mp; 3541 struct file *fp; 3542 int vfslocked; 3543 int error, lock_flags; 3544 3545 AUDIT_ARG_FD(uap->fd); 3546 if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FSYNC, 3547 &fp)) != 0) 3548 return (error); 3549 vp = fp->f_vnode; 3550 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3551 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 3552 goto drop; 3553 if (MNT_SHARED_WRITES(mp) || 3554 ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { 3555 lock_flags = LK_SHARED; 3556 } else { 3557 lock_flags = LK_EXCLUSIVE; 3558 } 3559 vn_lock(vp, lock_flags | LK_RETRY); 3560 AUDIT_ARG_VNODE1(vp); 3561 if (vp->v_object != NULL) { 3562 VM_OBJECT_LOCK(vp->v_object); 3563 vm_object_page_clean(vp->v_object, 0, 0, 0); 3564 VM_OBJECT_UNLOCK(vp->v_object); 3565 } 3566 error = VOP_FSYNC(vp, MNT_WAIT, td); 3567 3568 VOP_UNLOCK(vp, 0); 3569 vn_finished_write(mp); 3570 drop: 3571 VFS_UNLOCK_GIANT(vfslocked); 3572 fdrop(fp, td); 3573 return (error); 3574 } 3575 3576 /* 3577 * Rename files. Source and destination must either both be directories, or 3578 * both not be directories. If target is a directory, it must be empty. 3579 */ 3580 #ifndef _SYS_SYSPROTO_H_ 3581 struct rename_args { 3582 char *from; 3583 char *to; 3584 }; 3585 #endif 3586 int 3587 sys_rename(td, uap) 3588 struct thread *td; 3589 register struct rename_args /* { 3590 char *from; 3591 char *to; 3592 } */ *uap; 3593 { 3594 3595 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); 3596 } 3597 3598 #ifndef _SYS_SYSPROTO_H_ 3599 struct renameat_args { 3600 int oldfd; 3601 char *old; 3602 int newfd; 3603 char *new; 3604 }; 3605 #endif 3606 int 3607 sys_renameat(struct thread *td, struct renameat_args *uap) 3608 { 3609 3610 return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, 3611 UIO_USERSPACE)); 3612 } 3613 3614 int 3615 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) 3616 { 3617 3618 return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); 3619 } 3620 3621 int 3622 kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, 3623 enum uio_seg pathseg) 3624 { 3625 struct mount *mp = NULL; 3626 struct vnode *tvp, *fvp, *tdvp; 3627 struct nameidata fromnd, tond; 3628 int tvfslocked; 3629 int fvfslocked; 3630 int error; 3631 3632 bwillwrite(); 3633 #ifdef MAC 3634 NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | 3635 MPSAFE | AUDITVNODE1, pathseg, old, oldfd, CAP_DELETE, td); 3636 #else 3637 NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | 3638 AUDITVNODE1, pathseg, old, oldfd, CAP_DELETE, td); 3639 #endif 3640 3641 if ((error = namei(&fromnd)) != 0) 3642 return (error); 3643 fvfslocked = NDHASGIANT(&fromnd); 3644 tvfslocked = 0; 3645 #ifdef MAC 3646 error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp, 3647 fromnd.ni_vp, &fromnd.ni_cnd); 3648 VOP_UNLOCK(fromnd.ni_dvp, 0); 3649 if (fromnd.ni_dvp != fromnd.ni_vp) 3650 VOP_UNLOCK(fromnd.ni_vp, 0); 3651 #endif 3652 fvp = fromnd.ni_vp; 3653 if (error == 0) 3654 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); 3655 if (error != 0) { 3656 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3657 vrele(fromnd.ni_dvp); 3658 vrele(fvp); 3659 goto out1; 3660 } 3661 NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | 3662 SAVESTART | MPSAFE | AUDITVNODE2, pathseg, new, newfd, CAP_CREATE, 3663 td); 3664 if (fromnd.ni_vp->v_type == VDIR) 3665 tond.ni_cnd.cn_flags |= WILLBEDIR; 3666 if ((error = namei(&tond)) != 0) { 3667 /* Translate error code for rename("dir1", "dir2/."). */ 3668 if (error == EISDIR && fvp->v_type == VDIR) 3669 error = EINVAL; 3670 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3671 vrele(fromnd.ni_dvp); 3672 vrele(fvp); 3673 vn_finished_write(mp); 3674 goto out1; 3675 } 3676 tvfslocked = NDHASGIANT(&tond); 3677 tdvp = tond.ni_dvp; 3678 tvp = tond.ni_vp; 3679 if (tvp != NULL) { 3680 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 3681 error = ENOTDIR; 3682 goto out; 3683 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 3684 error = EISDIR; 3685 goto out; 3686 } 3687 } 3688 if (fvp == tdvp) { 3689 error = EINVAL; 3690 goto out; 3691 } 3692 /* 3693 * If the source is the same as the destination (that is, if they 3694 * are links to the same vnode), then there is nothing to do. 3695 */ 3696 if (fvp == tvp) 3697 error = -1; 3698 #ifdef MAC 3699 else 3700 error = mac_vnode_check_rename_to(td->td_ucred, tdvp, 3701 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); 3702 #endif 3703 out: 3704 if (!error) { 3705 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 3706 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 3707 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3708 NDFREE(&tond, NDF_ONLY_PNBUF); 3709 } else { 3710 NDFREE(&fromnd, NDF_ONLY_PNBUF); 3711 NDFREE(&tond, NDF_ONLY_PNBUF); 3712 if (tvp) 3713 vput(tvp); 3714 if (tdvp == tvp) 3715 vrele(tdvp); 3716 else 3717 vput(tdvp); 3718 vrele(fromnd.ni_dvp); 3719 vrele(fvp); 3720 } 3721 vrele(tond.ni_startdir); 3722 vn_finished_write(mp); 3723 out1: 3724 if (fromnd.ni_startdir) 3725 vrele(fromnd.ni_startdir); 3726 VFS_UNLOCK_GIANT(fvfslocked); 3727 VFS_UNLOCK_GIANT(tvfslocked); 3728 if (error == -1) 3729 return (0); 3730 return (error); 3731 } 3732 3733 /* 3734 * Make a directory file. 3735 */ 3736 #ifndef _SYS_SYSPROTO_H_ 3737 struct mkdir_args { 3738 char *path; 3739 int mode; 3740 }; 3741 #endif 3742 int 3743 sys_mkdir(td, uap) 3744 struct thread *td; 3745 register struct mkdir_args /* { 3746 char *path; 3747 int mode; 3748 } */ *uap; 3749 { 3750 3751 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); 3752 } 3753 3754 #ifndef _SYS_SYSPROTO_H_ 3755 struct mkdirat_args { 3756 int fd; 3757 char *path; 3758 mode_t mode; 3759 }; 3760 #endif 3761 int 3762 sys_mkdirat(struct thread *td, struct mkdirat_args *uap) 3763 { 3764 3765 return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); 3766 } 3767 3768 int 3769 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) 3770 { 3771 3772 return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); 3773 } 3774 3775 int 3776 kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, 3777 int mode) 3778 { 3779 struct mount *mp; 3780 struct vnode *vp; 3781 struct vattr vattr; 3782 int error; 3783 struct nameidata nd; 3784 int vfslocked; 3785 3786 AUDIT_ARG_MODE(mode); 3787 restart: 3788 bwillwrite(); 3789 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | 3790 AUDITVNODE1, segflg, path, fd, CAP_MKDIR, td); 3791 nd.ni_cnd.cn_flags |= WILLBEDIR; 3792 if ((error = namei(&nd)) != 0) 3793 return (error); 3794 vfslocked = NDHASGIANT(&nd); 3795 vp = nd.ni_vp; 3796 if (vp != NULL) { 3797 NDFREE(&nd, NDF_ONLY_PNBUF); 3798 /* 3799 * XXX namei called with LOCKPARENT but not LOCKLEAF has 3800 * the strange behaviour of leaving the vnode unlocked 3801 * if the target is the same vnode as the parent. 3802 */ 3803 if (vp == nd.ni_dvp) 3804 vrele(nd.ni_dvp); 3805 else 3806 vput(nd.ni_dvp); 3807 vrele(vp); 3808 VFS_UNLOCK_GIANT(vfslocked); 3809 return (EEXIST); 3810 } 3811 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3812 NDFREE(&nd, NDF_ONLY_PNBUF); 3813 vput(nd.ni_dvp); 3814 VFS_UNLOCK_GIANT(vfslocked); 3815 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3816 return (error); 3817 goto restart; 3818 } 3819 VATTR_NULL(&vattr); 3820 vattr.va_type = VDIR; 3821 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; 3822 #ifdef MAC 3823 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, 3824 &vattr); 3825 if (error) 3826 goto out; 3827 #endif 3828 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 3829 #ifdef MAC 3830 out: 3831 #endif 3832 NDFREE(&nd, NDF_ONLY_PNBUF); 3833 vput(nd.ni_dvp); 3834 if (!error) 3835 vput(nd.ni_vp); 3836 vn_finished_write(mp); 3837 VFS_UNLOCK_GIANT(vfslocked); 3838 return (error); 3839 } 3840 3841 /* 3842 * Remove a directory file. 3843 */ 3844 #ifndef _SYS_SYSPROTO_H_ 3845 struct rmdir_args { 3846 char *path; 3847 }; 3848 #endif 3849 int 3850 sys_rmdir(td, uap) 3851 struct thread *td; 3852 struct rmdir_args /* { 3853 char *path; 3854 } */ *uap; 3855 { 3856 3857 return (kern_rmdir(td, uap->path, UIO_USERSPACE)); 3858 } 3859 3860 int 3861 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) 3862 { 3863 3864 return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); 3865 } 3866 3867 int 3868 kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) 3869 { 3870 struct mount *mp; 3871 struct vnode *vp; 3872 int error; 3873 struct nameidata nd; 3874 int vfslocked; 3875 3876 restart: 3877 bwillwrite(); 3878 NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | 3879 AUDITVNODE1, pathseg, path, fd, CAP_RMDIR, td); 3880 if ((error = namei(&nd)) != 0) 3881 return (error); 3882 vfslocked = NDHASGIANT(&nd); 3883 vp = nd.ni_vp; 3884 if (vp->v_type != VDIR) { 3885 error = ENOTDIR; 3886 goto out; 3887 } 3888 /* 3889 * No rmdir "." please. 3890 */ 3891 if (nd.ni_dvp == vp) { 3892 error = EINVAL; 3893 goto out; 3894 } 3895 /* 3896 * The root of a mounted filesystem cannot be deleted. 3897 */ 3898 if (vp->v_vflag & VV_ROOT) { 3899 error = EBUSY; 3900 goto out; 3901 } 3902 #ifdef MAC 3903 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, 3904 &nd.ni_cnd); 3905 if (error) 3906 goto out; 3907 #endif 3908 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { 3909 NDFREE(&nd, NDF_ONLY_PNBUF); 3910 vput(vp); 3911 if (nd.ni_dvp == vp) 3912 vrele(nd.ni_dvp); 3913 else 3914 vput(nd.ni_dvp); 3915 VFS_UNLOCK_GIANT(vfslocked); 3916 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) 3917 return (error); 3918 goto restart; 3919 } 3920 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 3921 vn_finished_write(mp); 3922 out: 3923 NDFREE(&nd, NDF_ONLY_PNBUF); 3924 vput(vp); 3925 if (nd.ni_dvp == vp) 3926 vrele(nd.ni_dvp); 3927 else 3928 vput(nd.ni_dvp); 3929 VFS_UNLOCK_GIANT(vfslocked); 3930 return (error); 3931 } 3932 3933 #ifdef COMPAT_43 3934 /* 3935 * Read a block of directory entries in a filesystem independent format. 3936 */ 3937 #ifndef _SYS_SYSPROTO_H_ 3938 struct ogetdirentries_args { 3939 int fd; 3940 char *buf; 3941 u_int count; 3942 long *basep; 3943 }; 3944 #endif 3945 int 3946 ogetdirentries(struct thread *td, struct ogetdirentries_args *uap) 3947 { 3948 long loff; 3949 int error; 3950 3951 error = kern_ogetdirentries(td, uap, &loff); 3952 if (error == 0) 3953 error = copyout(&loff, uap->basep, sizeof(long)); 3954 return (error); 3955 } 3956 3957 int 3958 kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, 3959 long *ploff) 3960 { 3961 struct vnode *vp; 3962 struct file *fp; 3963 struct uio auio, kuio; 3964 struct iovec aiov, kiov; 3965 struct dirent *dp, *edp; 3966 caddr_t dirbuf; 3967 int error, eofflag, readcnt, vfslocked; 3968 long loff; 3969 off_t foffset; 3970 3971 /* XXX arbitrary sanity limit on `count'. */ 3972 if (uap->count > 64 * 1024) 3973 return (EINVAL); 3974 if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, 3975 &fp)) != 0) 3976 return (error); 3977 if ((fp->f_flag & FREAD) == 0) { 3978 fdrop(fp, td); 3979 return (EBADF); 3980 } 3981 vp = fp->f_vnode; 3982 foffset = foffset_lock(fp, 0); 3983 unionread: 3984 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 3985 if (vp->v_type != VDIR) { 3986 VFS_UNLOCK_GIANT(vfslocked); 3987 foffset_unlock(fp, foffset, 0); 3988 fdrop(fp, td); 3989 return (EINVAL); 3990 } 3991 aiov.iov_base = uap->buf; 3992 aiov.iov_len = uap->count; 3993 auio.uio_iov = &aiov; 3994 auio.uio_iovcnt = 1; 3995 auio.uio_rw = UIO_READ; 3996 auio.uio_segflg = UIO_USERSPACE; 3997 auio.uio_td = td; 3998 auio.uio_resid = uap->count; 3999 vn_lock(vp, LK_SHARED | LK_RETRY); 4000 loff = auio.uio_offset = foffset; 4001 #ifdef MAC 4002 error = mac_vnode_check_readdir(td->td_ucred, vp); 4003 if (error) { 4004 VOP_UNLOCK(vp, 0); 4005 VFS_UNLOCK_GIANT(vfslocked); 4006 foffset_unlock(fp, foffset, FOF_NOUPDATE); 4007 fdrop(fp, td); 4008 return (error); 4009 } 4010 #endif 4011 # if (BYTE_ORDER != LITTLE_ENDIAN) 4012 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 4013 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 4014 NULL, NULL); 4015 foffset = auio.uio_offset; 4016 } else 4017 # endif 4018 { 4019 kuio = auio; 4020 kuio.uio_iov = &kiov; 4021 kuio.uio_segflg = UIO_SYSSPACE; 4022 kiov.iov_len = uap->count; 4023 dirbuf = malloc(uap->count, M_TEMP, M_WAITOK); 4024 kiov.iov_base = dirbuf; 4025 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 4026 NULL, NULL); 4027 foffset = kuio.uio_offset; 4028 if (error == 0) { 4029 readcnt = uap->count - kuio.uio_resid; 4030 edp = (struct dirent *)&dirbuf[readcnt]; 4031 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 4032 # if (BYTE_ORDER == LITTLE_ENDIAN) 4033 /* 4034 * The expected low byte of 4035 * dp->d_namlen is our dp->d_type. 4036 * The high MBZ byte of dp->d_namlen 4037 * is our dp->d_namlen. 4038 */ 4039 dp->d_type = dp->d_namlen; 4040 dp->d_namlen = 0; 4041 # else 4042 /* 4043 * The dp->d_type is the high byte 4044 * of the expected dp->d_namlen, 4045 * so must be zero'ed. 4046 */ 4047 dp->d_type = 0; 4048 # endif 4049 if (dp->d_reclen > 0) { 4050 dp = (struct dirent *) 4051 ((char *)dp + dp->d_reclen); 4052 } else { 4053 error = EIO; 4054 break; 4055 } 4056 } 4057 if (dp >= edp) 4058 error = uiomove(dirbuf, readcnt, &auio); 4059 } 4060 free(dirbuf, M_TEMP); 4061 } 4062 if (error) { 4063 VOP_UNLOCK(vp, 0); 4064 VFS_UNLOCK_GIANT(vfslocked); 4065 foffset_unlock(fp, foffset, 0); 4066 fdrop(fp, td); 4067 return (error); 4068 } 4069 if (uap->count == auio.uio_resid && 4070 (vp->v_vflag & VV_ROOT) && 4071 (vp->v_mount->mnt_flag & MNT_UNION)) { 4072 struct vnode *tvp = vp; 4073 vp = vp->v_mount->mnt_vnodecovered; 4074 VREF(vp); 4075 fp->f_vnode = vp; 4076 fp->f_data = vp; 4077 foffset = 0; 4078 vput(tvp); 4079 VFS_UNLOCK_GIANT(vfslocked); 4080 goto unionread; 4081 } 4082 VOP_UNLOCK(vp, 0); 4083 VFS_UNLOCK_GIANT(vfslocked); 4084 foffset_unlock(fp, foffset, 0); 4085 fdrop(fp, td); 4086 td->td_retval[0] = uap->count - auio.uio_resid; 4087 if (error == 0) 4088 *ploff = loff; 4089 return (error); 4090 } 4091 #endif /* COMPAT_43 */ 4092 4093 /* 4094 * Read a block of directory entries in a filesystem independent format. 4095 */ 4096 #ifndef _SYS_SYSPROTO_H_ 4097 struct getdirentries_args { 4098 int fd; 4099 char *buf; 4100 u_int count; 4101 long *basep; 4102 }; 4103 #endif 4104 int 4105 sys_getdirentries(td, uap) 4106 struct thread *td; 4107 register struct getdirentries_args /* { 4108 int fd; 4109 char *buf; 4110 u_int count; 4111 long *basep; 4112 } */ *uap; 4113 { 4114 long base; 4115 int error; 4116 4117 error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, 4118 NULL, UIO_USERSPACE); 4119 if (error) 4120 return (error); 4121 if (uap->basep != NULL) 4122 error = copyout(&base, uap->basep, sizeof(long)); 4123 return (error); 4124 } 4125 4126 int 4127 kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, 4128 long *basep, ssize_t *residp, enum uio_seg bufseg) 4129 { 4130 struct vnode *vp; 4131 struct file *fp; 4132 struct uio auio; 4133 struct iovec aiov; 4134 int vfslocked; 4135 long loff; 4136 int error, eofflag; 4137 off_t foffset; 4138 4139 AUDIT_ARG_FD(fd); 4140 if (count > IOSIZE_MAX) 4141 return (EINVAL); 4142 auio.uio_resid = count; 4143 if ((error = getvnode(td->td_proc->p_fd, fd, CAP_READ | CAP_SEEK, 4144 &fp)) != 0) 4145 return (error); 4146 if ((fp->f_flag & FREAD) == 0) { 4147 fdrop(fp, td); 4148 return (EBADF); 4149 } 4150 vp = fp->f_vnode; 4151 foffset = foffset_lock(fp, 0); 4152 unionread: 4153 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 4154 if (vp->v_type != VDIR) { 4155 VFS_UNLOCK_GIANT(vfslocked); 4156 error = EINVAL; 4157 goto fail; 4158 } 4159 aiov.iov_base = buf; 4160 aiov.iov_len = count; 4161 auio.uio_iov = &aiov; 4162 auio.uio_iovcnt = 1; 4163 auio.uio_rw = UIO_READ; 4164 auio.uio_segflg = bufseg; 4165 auio.uio_td = td; 4166 vn_lock(vp, LK_SHARED | LK_RETRY); 4167 AUDIT_ARG_VNODE1(vp); 4168 loff = auio.uio_offset = foffset; 4169 #ifdef MAC 4170 error = mac_vnode_check_readdir(td->td_ucred, vp); 4171 if (error == 0) 4172 #endif 4173 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, 4174 NULL); 4175 foffset = auio.uio_offset; 4176 if (error) { 4177 VOP_UNLOCK(vp, 0); 4178 VFS_UNLOCK_GIANT(vfslocked); 4179 goto fail; 4180 } 4181 if (count == auio.uio_resid && 4182 (vp->v_vflag & VV_ROOT) && 4183 (vp->v_mount->mnt_flag & MNT_UNION)) { 4184 struct vnode *tvp = vp; 4185 vp = vp->v_mount->mnt_vnodecovered; 4186 VREF(vp); 4187 fp->f_vnode = vp; 4188 fp->f_data = vp; 4189 foffset = 0; 4190 vput(tvp); 4191 VFS_UNLOCK_GIANT(vfslocked); 4192 goto unionread; 4193 } 4194 VOP_UNLOCK(vp, 0); 4195 VFS_UNLOCK_GIANT(vfslocked); 4196 *basep = loff; 4197 if (residp != NULL) 4198 *residp = auio.uio_resid; 4199 td->td_retval[0] = count - auio.uio_resid; 4200 fail: 4201 foffset_unlock(fp, foffset, 0); 4202 fdrop(fp, td); 4203 return (error); 4204 } 4205 4206 #ifndef _SYS_SYSPROTO_H_ 4207 struct getdents_args { 4208 int fd; 4209 char *buf; 4210 size_t count; 4211 }; 4212 #endif 4213 int 4214 sys_getdents(td, uap) 4215 struct thread *td; 4216 register struct getdents_args /* { 4217 int fd; 4218 char *buf; 4219 u_int count; 4220 } */ *uap; 4221 { 4222 struct getdirentries_args ap; 4223 ap.fd = uap->fd; 4224 ap.buf = uap->buf; 4225 ap.count = uap->count; 4226 ap.basep = NULL; 4227 return (sys_getdirentries(td, &ap)); 4228 } 4229 4230 /* 4231 * Set the mode mask for creation of filesystem nodes. 4232 */ 4233 #ifndef _SYS_SYSPROTO_H_ 4234 struct umask_args { 4235 int newmask; 4236 }; 4237 #endif 4238 int 4239 sys_umask(td, uap) 4240 struct thread *td; 4241 struct umask_args /* { 4242 int newmask; 4243 } */ *uap; 4244 { 4245 register struct filedesc *fdp; 4246 4247 FILEDESC_XLOCK(td->td_proc->p_fd); 4248 fdp = td->td_proc->p_fd; 4249 td->td_retval[0] = fdp->fd_cmask; 4250 fdp->fd_cmask = uap->newmask & ALLPERMS; 4251 FILEDESC_XUNLOCK(td->td_proc->p_fd); 4252 return (0); 4253 } 4254 4255 /* 4256 * Void all references to file by ripping underlying filesystem away from 4257 * vnode. 4258 */ 4259 #ifndef _SYS_SYSPROTO_H_ 4260 struct revoke_args { 4261 char *path; 4262 }; 4263 #endif 4264 int 4265 sys_revoke(td, uap) 4266 struct thread *td; 4267 register struct revoke_args /* { 4268 char *path; 4269 } */ *uap; 4270 { 4271 struct vnode *vp; 4272 struct vattr vattr; 4273 int error; 4274 struct nameidata nd; 4275 int vfslocked; 4276 4277 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4278 UIO_USERSPACE, uap->path, td); 4279 if ((error = namei(&nd)) != 0) 4280 return (error); 4281 vfslocked = NDHASGIANT(&nd); 4282 vp = nd.ni_vp; 4283 NDFREE(&nd, NDF_ONLY_PNBUF); 4284 if (vp->v_type != VCHR || vp->v_rdev == NULL) { 4285 error = EINVAL; 4286 goto out; 4287 } 4288 #ifdef MAC 4289 error = mac_vnode_check_revoke(td->td_ucred, vp); 4290 if (error) 4291 goto out; 4292 #endif 4293 error = VOP_GETATTR(vp, &vattr, td->td_ucred); 4294 if (error) 4295 goto out; 4296 if (td->td_ucred->cr_uid != vattr.va_uid) { 4297 error = priv_check(td, PRIV_VFS_ADMIN); 4298 if (error) 4299 goto out; 4300 } 4301 if (vcount(vp) > 1) 4302 VOP_REVOKE(vp, REVOKEALL); 4303 out: 4304 vput(vp); 4305 VFS_UNLOCK_GIANT(vfslocked); 4306 return (error); 4307 } 4308 4309 /* 4310 * Convert a user file descriptor to a kernel file entry and check that, if it 4311 * is a capability, the correct rights are present. A reference on the file 4312 * entry is held upon returning. 4313 */ 4314 int 4315 getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, 4316 struct file **fpp) 4317 { 4318 struct file *fp; 4319 #ifdef CAPABILITIES 4320 struct file *fp_fromcap; 4321 int error; 4322 #endif 4323 4324 if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) 4325 return (EBADF); 4326 #ifdef CAPABILITIES 4327 /* 4328 * If the file descriptor is for a capability, test rights and use the 4329 * file descriptor referenced by the capability. 4330 */ 4331 error = cap_funwrap(fp, rights, &fp_fromcap); 4332 if (error) { 4333 fdrop(fp, curthread); 4334 return (error); 4335 } 4336 if (fp != fp_fromcap) { 4337 fhold(fp_fromcap); 4338 fdrop(fp, curthread); 4339 fp = fp_fromcap; 4340 } 4341 #endif /* CAPABILITIES */ 4342 4343 /* 4344 * The file could be not of the vnode type, or it may be not 4345 * yet fully initialized, in which case the f_vnode pointer 4346 * may be set, but f_ops is still badfileops. E.g., 4347 * devfs_open() transiently create such situation to 4348 * facilitate csw d_fdopen(). 4349 * 4350 * Dupfdopen() handling in kern_openat() installs the 4351 * half-baked file into the process descriptor table, allowing 4352 * other thread to dereference it. Guard against the race by 4353 * checking f_ops. 4354 */ 4355 if (fp->f_vnode == NULL || fp->f_ops == &badfileops) { 4356 fdrop(fp, curthread); 4357 return (EINVAL); 4358 } 4359 *fpp = fp; 4360 return (0); 4361 } 4362 4363 4364 /* 4365 * Get an (NFS) file handle. 4366 */ 4367 #ifndef _SYS_SYSPROTO_H_ 4368 struct lgetfh_args { 4369 char *fname; 4370 fhandle_t *fhp; 4371 }; 4372 #endif 4373 int 4374 sys_lgetfh(td, uap) 4375 struct thread *td; 4376 register struct lgetfh_args *uap; 4377 { 4378 struct nameidata nd; 4379 fhandle_t fh; 4380 register struct vnode *vp; 4381 int vfslocked; 4382 int error; 4383 4384 error = priv_check(td, PRIV_VFS_GETFH); 4385 if (error) 4386 return (error); 4387 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4388 UIO_USERSPACE, uap->fname, td); 4389 error = namei(&nd); 4390 if (error) 4391 return (error); 4392 vfslocked = NDHASGIANT(&nd); 4393 NDFREE(&nd, NDF_ONLY_PNBUF); 4394 vp = nd.ni_vp; 4395 bzero(&fh, sizeof(fh)); 4396 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4397 error = VOP_VPTOFH(vp, &fh.fh_fid); 4398 vput(vp); 4399 VFS_UNLOCK_GIANT(vfslocked); 4400 if (error) 4401 return (error); 4402 error = copyout(&fh, uap->fhp, sizeof (fh)); 4403 return (error); 4404 } 4405 4406 #ifndef _SYS_SYSPROTO_H_ 4407 struct getfh_args { 4408 char *fname; 4409 fhandle_t *fhp; 4410 }; 4411 #endif 4412 int 4413 sys_getfh(td, uap) 4414 struct thread *td; 4415 register struct getfh_args *uap; 4416 { 4417 struct nameidata nd; 4418 fhandle_t fh; 4419 register struct vnode *vp; 4420 int vfslocked; 4421 int error; 4422 4423 error = priv_check(td, PRIV_VFS_GETFH); 4424 if (error) 4425 return (error); 4426 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 4427 UIO_USERSPACE, uap->fname, td); 4428 error = namei(&nd); 4429 if (error) 4430 return (error); 4431 vfslocked = NDHASGIANT(&nd); 4432 NDFREE(&nd, NDF_ONLY_PNBUF); 4433 vp = nd.ni_vp; 4434 bzero(&fh, sizeof(fh)); 4435 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 4436 error = VOP_VPTOFH(vp, &fh.fh_fid); 4437 vput(vp); 4438 VFS_UNLOCK_GIANT(vfslocked); 4439 if (error) 4440 return (error); 4441 error = copyout(&fh, uap->fhp, sizeof (fh)); 4442 return (error); 4443 } 4444 4445 /* 4446 * syscall for the rpc.lockd to use to translate a NFS file handle into an 4447 * open descriptor. 4448 * 4449 * warning: do not remove the priv_check() call or this becomes one giant 4450 * security hole. 4451 */ 4452 #ifndef _SYS_SYSPROTO_H_ 4453 struct fhopen_args { 4454 const struct fhandle *u_fhp; 4455 int flags; 4456 }; 4457 #endif 4458 int 4459 sys_fhopen(td, uap) 4460 struct thread *td; 4461 struct fhopen_args /* { 4462 const struct fhandle *u_fhp; 4463 int flags; 4464 } */ *uap; 4465 { 4466 struct mount *mp; 4467 struct vnode *vp; 4468 struct fhandle fhp; 4469 struct file *fp; 4470 int fmode, error; 4471 int vfslocked; 4472 int indx; 4473 4474 error = priv_check(td, PRIV_VFS_FHOPEN); 4475 if (error) 4476 return (error); 4477 indx = -1; 4478 fmode = FFLAGS(uap->flags); 4479 /* why not allow a non-read/write open for our lockd? */ 4480 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 4481 return (EINVAL); 4482 error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); 4483 if (error) 4484 return(error); 4485 /* find the mount point */ 4486 mp = vfs_busyfs(&fhp.fh_fsid); 4487 if (mp == NULL) 4488 return (ESTALE); 4489 vfslocked = VFS_LOCK_GIANT(mp); 4490 /* now give me my vnode, it gets returned to me locked */ 4491 error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); 4492 vfs_unbusy(mp); 4493 if (error) { 4494 VFS_UNLOCK_GIANT(vfslocked); 4495 return (error); 4496 } 4497 4498 error = falloc_noinstall(td, &fp); 4499 if (error) { 4500 vput(vp); 4501 VFS_UNLOCK_GIANT(vfslocked); 4502 return (error); 4503 } 4504 /* 4505 * An extra reference on `fp' has been held for us by 4506 * falloc_noinstall(). 4507 */ 4508 4509 #ifdef INVARIANTS 4510 td->td_dupfd = -1; 4511 #endif 4512 error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp); 4513 if (error) { 4514 KASSERT(fp->f_ops == &badfileops, 4515 ("VOP_OPEN in fhopen() set f_ops")); 4516 KASSERT(td->td_dupfd < 0, 4517 ("fhopen() encountered fdopen()")); 4518 4519 vput(vp); 4520 goto bad; 4521 } 4522 #ifdef INVARIANTS 4523 td->td_dupfd = 0; 4524 #endif 4525 fp->f_vnode = vp; 4526 fp->f_seqcount = 1; 4527 finit(fp, (fmode & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, vp, 4528 &vnops); 4529 VOP_UNLOCK(vp, 0); 4530 if (fmode & O_TRUNC) { 4531 error = fo_truncate(fp, 0, td->td_ucred, td); 4532 if (error) 4533 goto bad; 4534 } 4535 4536 error = finstall(td, fp, &indx, fmode); 4537 bad: 4538 VFS_UNLOCK_GIANT(vfslocked); 4539 fdrop(fp, td); 4540 td->td_retval[0] = indx; 4541 return (error); 4542 } 4543 4544 /* 4545 * Stat an (NFS) file handle. 4546 */ 4547 #ifndef _SYS_SYSPROTO_H_ 4548 struct fhstat_args { 4549 struct fhandle *u_fhp; 4550 struct stat *sb; 4551 }; 4552 #endif 4553 int 4554 sys_fhstat(td, uap) 4555 struct thread *td; 4556 register struct fhstat_args /* { 4557 struct fhandle *u_fhp; 4558 struct stat *sb; 4559 } */ *uap; 4560 { 4561 struct stat sb; 4562 struct fhandle fh; 4563 int error; 4564 4565 error = copyin(uap->u_fhp, &fh, sizeof(fh)); 4566 if (error != 0) 4567 return (error); 4568 error = kern_fhstat(td, fh, &sb); 4569 if (error != 0) 4570 return (error); 4571 error = copyout(&sb, uap->sb, sizeof(sb)); 4572 return (error); 4573 } 4574 4575 int 4576 kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb) 4577 { 4578 struct mount *mp; 4579 struct vnode *vp; 4580 int vfslocked; 4581 int error; 4582 4583 error = priv_check(td, PRIV_VFS_FHSTAT); 4584 if (error) 4585 return (error); 4586 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) 4587 return (ESTALE); 4588 vfslocked = VFS_LOCK_GIANT(mp); 4589 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); 4590 vfs_unbusy(mp); 4591 if (error) { 4592 VFS_UNLOCK_GIANT(vfslocked); 4593 return (error); 4594 } 4595 error = vn_stat(vp, sb, td->td_ucred, NOCRED, td); 4596 vput(vp); 4597 VFS_UNLOCK_GIANT(vfslocked); 4598 return (error); 4599 } 4600 4601 /* 4602 * Implement fstatfs() for (NFS) file handles. 4603 */ 4604 #ifndef _SYS_SYSPROTO_H_ 4605 struct fhstatfs_args { 4606 struct fhandle *u_fhp; 4607 struct statfs *buf; 4608 }; 4609 #endif 4610 int 4611 sys_fhstatfs(td, uap) 4612 struct thread *td; 4613 struct fhstatfs_args /* { 4614 struct fhandle *u_fhp; 4615 struct statfs *buf; 4616 } */ *uap; 4617 { 4618 struct statfs sf; 4619 fhandle_t fh; 4620 int error; 4621 4622 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); 4623 if (error) 4624 return (error); 4625 error = kern_fhstatfs(td, fh, &sf); 4626 if (error) 4627 return (error); 4628 return (copyout(&sf, uap->buf, sizeof(sf))); 4629 } 4630 4631 int 4632 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) 4633 { 4634 struct statfs *sp; 4635 struct mount *mp; 4636 struct vnode *vp; 4637 int vfslocked; 4638 int error; 4639 4640 error = priv_check(td, PRIV_VFS_FHSTATFS); 4641 if (error) 4642 return (error); 4643 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) 4644 return (ESTALE); 4645 vfslocked = VFS_LOCK_GIANT(mp); 4646 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); 4647 if (error) { 4648 vfs_unbusy(mp); 4649 VFS_UNLOCK_GIANT(vfslocked); 4650 return (error); 4651 } 4652 vput(vp); 4653 error = prison_canseemount(td->td_ucred, mp); 4654 if (error) 4655 goto out; 4656 #ifdef MAC 4657 error = mac_mount_check_stat(td->td_ucred, mp); 4658 if (error) 4659 goto out; 4660 #endif 4661 /* 4662 * Set these in case the underlying filesystem fails to do so. 4663 */ 4664 sp = &mp->mnt_stat; 4665 sp->f_version = STATFS_VERSION; 4666 sp->f_namemax = NAME_MAX; 4667 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 4668 error = VFS_STATFS(mp, sp); 4669 if (error == 0) 4670 *buf = *sp; 4671 out: 4672 vfs_unbusy(mp); 4673 VFS_UNLOCK_GIANT(vfslocked); 4674 return (error); 4675 } 4676 4677 int 4678 kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) 4679 { 4680 struct file *fp; 4681 struct mount *mp; 4682 struct vnode *vp; 4683 off_t olen, ooffset; 4684 int error, vfslocked; 4685 4686 fp = NULL; 4687 vfslocked = 0; 4688 error = fget(td, fd, CAP_WRITE, &fp); 4689 if (error != 0) 4690 goto out; 4691 4692 switch (fp->f_type) { 4693 case DTYPE_VNODE: 4694 break; 4695 case DTYPE_PIPE: 4696 case DTYPE_FIFO: 4697 error = ESPIPE; 4698 goto out; 4699 default: 4700 error = ENODEV; 4701 goto out; 4702 } 4703 if ((fp->f_flag & FWRITE) == 0) { 4704 error = EBADF; 4705 goto out; 4706 } 4707 vp = fp->f_vnode; 4708 if (vp->v_type != VREG) { 4709 error = ENODEV; 4710 goto out; 4711 } 4712 if (offset < 0 || len <= 0) { 4713 error = EINVAL; 4714 goto out; 4715 } 4716 /* Check for wrap. */ 4717 if (offset > OFF_MAX - len) { 4718 error = EFBIG; 4719 goto out; 4720 } 4721 4722 /* Allocating blocks may take a long time, so iterate. */ 4723 for (;;) { 4724 olen = len; 4725 ooffset = offset; 4726 4727 bwillwrite(); 4728 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 4729 mp = NULL; 4730 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 4731 if (error != 0) { 4732 VFS_UNLOCK_GIANT(vfslocked); 4733 break; 4734 } 4735 error = vn_lock(vp, LK_EXCLUSIVE); 4736 if (error != 0) { 4737 vn_finished_write(mp); 4738 VFS_UNLOCK_GIANT(vfslocked); 4739 break; 4740 } 4741 #ifdef MAC 4742 error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); 4743 if (error == 0) 4744 #endif 4745 error = VOP_ALLOCATE(vp, &offset, &len); 4746 VOP_UNLOCK(vp, 0); 4747 vn_finished_write(mp); 4748 VFS_UNLOCK_GIANT(vfslocked); 4749 4750 if (olen + ooffset != offset + len) { 4751 panic("offset + len changed from %jx/%jx to %jx/%jx", 4752 ooffset, olen, offset, len); 4753 } 4754 if (error != 0 || len == 0) 4755 break; 4756 KASSERT(olen > len, ("Iteration did not make progress?")); 4757 maybe_yield(); 4758 } 4759 out: 4760 if (fp != NULL) 4761 fdrop(fp, td); 4762 return (error); 4763 } 4764 4765 int 4766 sys_posix_fallocate(struct thread *td, struct posix_fallocate_args *uap) 4767 { 4768 4769 return (kern_posix_fallocate(td, uap->fd, uap->offset, uap->len)); 4770 } 4771 4772 /* 4773 * Unlike madvise(2), we do not make a best effort to remember every 4774 * possible caching hint. Instead, we remember the last setting with 4775 * the exception that we will allow POSIX_FADV_NORMAL to adjust the 4776 * region of any current setting. 4777 */ 4778 int 4779 kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, 4780 int advice) 4781 { 4782 struct fadvise_info *fa, *new; 4783 struct file *fp; 4784 struct vnode *vp; 4785 off_t end; 4786 int error; 4787 4788 if (offset < 0 || len < 0 || offset > OFF_MAX - len) 4789 return (EINVAL); 4790 switch (advice) { 4791 case POSIX_FADV_SEQUENTIAL: 4792 case POSIX_FADV_RANDOM: 4793 case POSIX_FADV_NOREUSE: 4794 new = malloc(sizeof(*fa), M_FADVISE, M_WAITOK); 4795 break; 4796 case POSIX_FADV_NORMAL: 4797 case POSIX_FADV_WILLNEED: 4798 case POSIX_FADV_DONTNEED: 4799 new = NULL; 4800 break; 4801 default: 4802 return (EINVAL); 4803 } 4804 /* XXX: CAP_POSIX_FADVISE? */ 4805 error = fget(td, fd, 0, &fp); 4806 if (error != 0) 4807 goto out; 4808 4809 switch (fp->f_type) { 4810 case DTYPE_VNODE: 4811 break; 4812 case DTYPE_PIPE: 4813 case DTYPE_FIFO: 4814 error = ESPIPE; 4815 goto out; 4816 default: 4817 error = ENODEV; 4818 goto out; 4819 } 4820 vp = fp->f_vnode; 4821 if (vp->v_type != VREG) { 4822 error = ENODEV; 4823 goto out; 4824 } 4825 if (len == 0) 4826 end = OFF_MAX; 4827 else 4828 end = offset + len - 1; 4829 switch (advice) { 4830 case POSIX_FADV_SEQUENTIAL: 4831 case POSIX_FADV_RANDOM: 4832 case POSIX_FADV_NOREUSE: 4833 /* 4834 * Try to merge any existing non-standard region with 4835 * this new region if possible, otherwise create a new 4836 * non-standard region for this request. 4837 */ 4838 mtx_pool_lock(mtxpool_sleep, fp); 4839 fa = fp->f_advice; 4840 if (fa != NULL && fa->fa_advice == advice && 4841 ((fa->fa_start <= end && fa->fa_end >= offset) || 4842 (end != OFF_MAX && fa->fa_start == end + 1) || 4843 (fa->fa_end != OFF_MAX && fa->fa_end + 1 == offset))) { 4844 if (offset < fa->fa_start) 4845 fa->fa_start = offset; 4846 if (end > fa->fa_end) 4847 fa->fa_end = end; 4848 } else { 4849 new->fa_advice = advice; 4850 new->fa_start = offset; 4851 new->fa_end = end; 4852 new->fa_prevstart = 0; 4853 new->fa_prevend = 0; 4854 fp->f_advice = new; 4855 new = fa; 4856 } 4857 mtx_pool_unlock(mtxpool_sleep, fp); 4858 break; 4859 case POSIX_FADV_NORMAL: 4860 /* 4861 * If a the "normal" region overlaps with an existing 4862 * non-standard region, trim or remove the 4863 * non-standard region. 4864 */ 4865 mtx_pool_lock(mtxpool_sleep, fp); 4866 fa = fp->f_advice; 4867 if (fa != NULL) { 4868 if (offset <= fa->fa_start && end >= fa->fa_end) { 4869 new = fa; 4870 fp->f_advice = NULL; 4871 } else if (offset <= fa->fa_start && 4872 end >= fa->fa_start) 4873 fa->fa_start = end + 1; 4874 else if (offset <= fa->fa_end && end >= fa->fa_end) 4875 fa->fa_end = offset - 1; 4876 else if (offset >= fa->fa_start && end <= fa->fa_end) { 4877 /* 4878 * If the "normal" region is a middle 4879 * portion of the existing 4880 * non-standard region, just remove 4881 * the whole thing rather than picking 4882 * one side or the other to 4883 * preserve. 4884 */ 4885 new = fa; 4886 fp->f_advice = NULL; 4887 } 4888 } 4889 mtx_pool_unlock(mtxpool_sleep, fp); 4890 break; 4891 case POSIX_FADV_WILLNEED: 4892 case POSIX_FADV_DONTNEED: 4893 error = VOP_ADVISE(vp, offset, end, advice); 4894 break; 4895 } 4896 out: 4897 if (fp != NULL) 4898 fdrop(fp, td); 4899 free(new, M_FADVISE); 4900 return (error); 4901 } 4902 4903 int 4904 sys_posix_fadvise(struct thread *td, struct posix_fadvise_args *uap) 4905 { 4906 4907 return (kern_posix_fadvise(td, uap->fd, uap->offset, uap->len, 4908 uap->advice)); 4909 } 4910