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