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