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