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