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