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