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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 39 * $FreeBSD$ 40 */ 41 42 /* For 4.3 integer FS ID compatibility */ 43 #include "opt_compat.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/buf.h> 48 #include <sys/sysent.h> 49 #include <sys/sysproto.h> 50 #include <sys/namei.h> 51 #include <sys/filedesc.h> 52 #include <sys/kernel.h> 53 #include <sys/fcntl.h> 54 #include <sys/file.h> 55 #include <sys/linker.h> 56 #include <sys/stat.h> 57 #include <sys/unistd.h> 58 #include <sys/vnode.h> 59 #include <sys/malloc.h> 60 #include <sys/mount.h> 61 #include <sys/proc.h> 62 #include <sys/dirent.h> 63 64 #include <miscfs/union/union.h> 65 66 #include <vm/vm.h> 67 #include <vm/vm_object.h> 68 #include <vm/vm_extern.h> 69 #include <vm/vm_zone.h> 70 #include <sys/sysctl.h> 71 72 static int change_dir __P((struct nameidata *ndp, struct proc *p)); 73 static void checkdirs __P((struct vnode *olddp)); 74 static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); 75 static int getutimes __P((const struct timeval *, struct timespec *)); 76 static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); 77 static int setfmode __P((struct proc *, struct vnode *, int)); 78 static int setfflags __P((struct proc *, struct vnode *, int)); 79 static int setutimes __P((struct proc *, struct vnode *, 80 const struct timespec *, int)); 81 static int usermount = 0; /* if 1, non-root can mount fs. */ 82 83 int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *)); 84 85 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); 86 87 /* 88 * Virtual File System System Calls 89 */ 90 91 /* 92 * Mount a file system. 93 */ 94 #ifndef _SYS_SYSPROTO_H_ 95 struct mount_args { 96 char *type; 97 char *path; 98 int flags; 99 caddr_t data; 100 }; 101 #endif 102 /* ARGSUSED */ 103 int 104 mount(p, uap) 105 struct proc *p; 106 register struct mount_args /* { 107 syscallarg(char *) type; 108 syscallarg(char *) path; 109 syscallarg(int) flags; 110 syscallarg(caddr_t) data; 111 } */ *uap; 112 { 113 struct vnode *vp; 114 struct mount *mp; 115 struct vfsconf *vfsp; 116 int error, flag = 0, flag2 = 0; 117 struct vattr va; 118 #ifdef COMPAT_43 119 u_long fstypenum; 120 #endif 121 struct nameidata nd; 122 char fstypename[MFSNAMELEN]; 123 124 if (usermount == 0 && (error = suser(p))) 125 return (error); 126 /* 127 * Do not allow NFS export by non-root users. 128 */ 129 if (SCARG(uap, flags) & MNT_EXPORTED) { 130 error = suser(p); 131 if (error) 132 return (error); 133 } 134 /* 135 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users 136 */ 137 if (suser_xxx(p->p_ucred, 0, 0)) 138 SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV; 139 /* 140 * Get vnode to be covered 141 */ 142 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 143 SCARG(uap, path), p); 144 if ((error = namei(&nd)) != 0) 145 return (error); 146 vp = nd.ni_vp; 147 if (SCARG(uap, flags) & MNT_UPDATE) { 148 if ((vp->v_flag & VROOT) == 0) { 149 vput(vp); 150 return (EINVAL); 151 } 152 mp = vp->v_mount; 153 flag = mp->mnt_flag; 154 flag2 = mp->mnt_kern_flag; 155 /* 156 * We only allow the filesystem to be reloaded if it 157 * is currently mounted read-only. 158 */ 159 if ((SCARG(uap, flags) & MNT_RELOAD) && 160 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 161 vput(vp); 162 return (EOPNOTSUPP); /* Needs translation */ 163 } 164 mp->mnt_flag |= 165 SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE); 166 /* 167 * Only root, or the user that did the original mount is 168 * permitted to update it. 169 */ 170 if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid && 171 (error = suser(p))) { 172 vput(vp); 173 return (error); 174 } 175 if (vfs_busy(mp, LK_NOWAIT, 0, p)) { 176 vput(vp); 177 return (EBUSY); 178 } 179 VOP_UNLOCK(vp, 0, p); 180 goto update; 181 } 182 /* 183 * If the user is not root, ensure that they own the directory 184 * onto which we are attempting to mount. 185 */ 186 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) || 187 (va.va_uid != p->p_ucred->cr_uid && 188 (error = suser(p)))) { 189 vput(vp); 190 return (error); 191 } 192 if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) 193 return (error); 194 if (vp->v_type != VDIR) { 195 vput(vp); 196 return (ENOTDIR); 197 } 198 #ifdef COMPAT_43 199 /* 200 * Historically filesystem types were identified by number. If we 201 * get an integer for the filesystem type instead of a string, we 202 * check to see if it matches one of the historic filesystem types. 203 */ 204 fstypenum = (uintptr_t)SCARG(uap, type); 205 if (fstypenum < maxvfsconf) { 206 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 207 if (vfsp->vfc_typenum == fstypenum) 208 break; 209 if (vfsp == NULL) { 210 vput(vp); 211 return (ENODEV); 212 } 213 strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN); 214 } else 215 #endif /* COMPAT_43 */ 216 if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) { 217 vput(vp); 218 return (error); 219 } 220 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 221 if (!strcmp(vfsp->vfc_name, fstypename)) 222 break; 223 if (vfsp == NULL) { 224 linker_file_t lf; 225 226 /* Refuse to load modules if securelevel raised */ 227 if (securelevel > 0) { 228 vput(vp); 229 return EPERM; 230 } 231 /* Only load modules for root (very important!) */ 232 if ((error = suser(p)) != 0) { 233 vput(vp); 234 return error; 235 } 236 error = linker_load_file(fstypename, &lf); 237 if (error || lf == NULL) { 238 vput(vp); 239 if (lf == NULL) 240 error = ENODEV; 241 return error; 242 } 243 lf->userrefs++; 244 /* lookup again, see if the VFS was loaded */ 245 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 246 if (!strcmp(vfsp->vfc_name, fstypename)) 247 break; 248 if (vfsp == NULL) { 249 lf->userrefs--; 250 linker_file_unload(lf); 251 vput(vp); 252 return (ENODEV); 253 } 254 } 255 simple_lock(&vp->v_interlock); 256 if ((vp->v_flag & VMOUNT) != 0 || 257 vp->v_mountedhere != NULL) { 258 simple_unlock(&vp->v_interlock); 259 vput(vp); 260 return (EBUSY); 261 } 262 vp->v_flag |= VMOUNT; 263 simple_unlock(&vp->v_interlock); 264 265 /* 266 * Allocate and initialize the filesystem. 267 */ 268 mp = (struct mount *)malloc((u_long)sizeof(struct mount), 269 M_MOUNT, M_WAITOK); 270 bzero((char *)mp, (u_long)sizeof(struct mount)); 271 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); 272 (void)vfs_busy(mp, LK_NOWAIT, 0, p); 273 mp->mnt_op = vfsp->vfc_vfsops; 274 mp->mnt_vfc = vfsp; 275 vfsp->vfc_refcount++; 276 mp->mnt_stat.f_type = vfsp->vfc_typenum; 277 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 278 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 279 mp->mnt_vnodecovered = vp; 280 mp->mnt_stat.f_owner = p->p_ucred->cr_uid; 281 VOP_UNLOCK(vp, 0, p); 282 update: 283 /* 284 * Set the mount level flags. 285 */ 286 if (SCARG(uap, flags) & MNT_RDONLY) 287 mp->mnt_flag |= MNT_RDONLY; 288 else if (mp->mnt_flag & MNT_RDONLY) 289 mp->mnt_kern_flag |= MNTK_WANTRDWR; 290 mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | 291 MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | 292 MNT_NOSYMFOLLOW | 293 MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 294 mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | 295 MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | 296 MNT_NOSYMFOLLOW | 297 MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 298 /* 299 * Mount the filesystem. 300 */ 301 error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p); 302 if (mp->mnt_flag & MNT_UPDATE) { 303 vrele(vp); 304 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 305 mp->mnt_flag &= ~MNT_RDONLY; 306 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE); 307 mp->mnt_kern_flag &=~ MNTK_WANTRDWR; 308 if (error) { 309 mp->mnt_flag = flag; 310 mp->mnt_kern_flag = flag2; 311 } 312 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 313 if (mp->mnt_syncer == NULL) 314 error = vfs_allocate_syncvnode(mp); 315 } else { 316 if (mp->mnt_syncer != NULL) 317 vrele(mp->mnt_syncer); 318 mp->mnt_syncer = NULL; 319 } 320 vfs_unbusy(mp, p); 321 return (error); 322 } 323 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 324 /* 325 * Put the new filesystem on the mount list after root. 326 */ 327 cache_purge(vp); 328 if (!error) { 329 simple_lock(&vp->v_interlock); 330 vp->v_flag &= ~VMOUNT; 331 vp->v_mountedhere = mp; 332 simple_unlock(&vp->v_interlock); 333 simple_lock(&mountlist_slock); 334 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 335 simple_unlock(&mountlist_slock); 336 checkdirs(vp); 337 VOP_UNLOCK(vp, 0, p); 338 if ((mp->mnt_flag & MNT_RDONLY) == 0) 339 error = vfs_allocate_syncvnode(mp); 340 vfs_unbusy(mp, p); 341 if ((error = VFS_START(mp, 0, p)) != 0) 342 vrele(vp); 343 } else { 344 simple_lock(&vp->v_interlock); 345 vp->v_flag &= ~VMOUNT; 346 simple_unlock(&vp->v_interlock); 347 mp->mnt_vfc->vfc_refcount--; 348 vfs_unbusy(mp, p); 349 free((caddr_t)mp, M_MOUNT); 350 vput(vp); 351 } 352 return (error); 353 } 354 355 /* 356 * Scan all active processes to see if any of them have a current 357 * or root directory onto which the new filesystem has just been 358 * mounted. If so, replace them with the new mount point. 359 */ 360 static void 361 checkdirs(olddp) 362 struct vnode *olddp; 363 { 364 struct filedesc *fdp; 365 struct vnode *newdp; 366 struct proc *p; 367 368 if (olddp->v_usecount == 1) 369 return; 370 if (VFS_ROOT(olddp->v_mountedhere, &newdp)) 371 panic("mount: lost mount"); 372 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 373 fdp = p->p_fd; 374 if (fdp->fd_cdir == olddp) { 375 vrele(fdp->fd_cdir); 376 VREF(newdp); 377 fdp->fd_cdir = newdp; 378 } 379 if (fdp->fd_rdir == olddp) { 380 vrele(fdp->fd_rdir); 381 VREF(newdp); 382 fdp->fd_rdir = newdp; 383 } 384 } 385 if (rootvnode == olddp) { 386 vrele(rootvnode); 387 VREF(newdp); 388 rootvnode = newdp; 389 } 390 vput(newdp); 391 } 392 393 /* 394 * Unmount a file system. 395 * 396 * Note: unmount takes a path to the vnode mounted on as argument, 397 * not special file (as before). 398 */ 399 #ifndef _SYS_SYSPROTO_H_ 400 struct unmount_args { 401 char *path; 402 int flags; 403 }; 404 #endif 405 /* ARGSUSED */ 406 int 407 unmount(p, uap) 408 struct proc *p; 409 register struct unmount_args /* { 410 syscallarg(char *) path; 411 syscallarg(int) flags; 412 } */ *uap; 413 { 414 register struct vnode *vp; 415 struct mount *mp; 416 int error; 417 struct nameidata nd; 418 419 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 420 SCARG(uap, path), p); 421 if ((error = namei(&nd)) != 0) 422 return (error); 423 vp = nd.ni_vp; 424 mp = vp->v_mount; 425 426 /* 427 * Only root, or the user that did the original mount is 428 * permitted to unmount this filesystem. 429 */ 430 if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) && 431 (error = suser(p))) { 432 vput(vp); 433 return (error); 434 } 435 436 /* 437 * Don't allow unmounting the root file system. 438 */ 439 if (mp->mnt_flag & MNT_ROOTFS) { 440 vput(vp); 441 return (EINVAL); 442 } 443 444 /* 445 * Must be the root of the filesystem 446 */ 447 if ((vp->v_flag & VROOT) == 0) { 448 vput(vp); 449 return (EINVAL); 450 } 451 vput(vp); 452 return (dounmount(mp, SCARG(uap, flags), p)); 453 } 454 455 /* 456 * Do the actual file system unmount. 457 */ 458 int 459 dounmount(mp, flags, p) 460 register struct mount *mp; 461 int flags; 462 struct proc *p; 463 { 464 struct vnode *coveredvp; 465 int error; 466 int async_flag; 467 468 simple_lock(&mountlist_slock); 469 mp->mnt_kern_flag |= MNTK_UNMOUNT; 470 lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p); 471 472 if (mp->mnt_flag & MNT_EXPUBLIC) 473 vfs_setpublicfs(NULL, NULL, NULL); 474 475 vfs_msync(mp, MNT_WAIT); 476 async_flag = mp->mnt_flag & MNT_ASYNC; 477 mp->mnt_flag &=~ MNT_ASYNC; 478 cache_purgevfs(mp); /* remove cache entries for this file sys */ 479 if (mp->mnt_syncer != NULL) 480 vrele(mp->mnt_syncer); 481 if (((mp->mnt_flag & MNT_RDONLY) || 482 (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) || 483 (flags & MNT_FORCE)) 484 error = VFS_UNMOUNT(mp, flags, p); 485 simple_lock(&mountlist_slock); 486 if (error) { 487 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 488 (void) vfs_allocate_syncvnode(mp); 489 mp->mnt_kern_flag &= ~MNTK_UNMOUNT; 490 mp->mnt_flag |= async_flag; 491 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, 492 &mountlist_slock, p); 493 if (mp->mnt_kern_flag & MNTK_MWAIT) 494 wakeup((caddr_t)mp); 495 return (error); 496 } 497 CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); 498 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { 499 coveredvp->v_mountedhere = (struct mount *)0; 500 vrele(coveredvp); 501 } 502 mp->mnt_vfc->vfc_refcount--; 503 if (mp->mnt_vnodelist.lh_first != NULL) 504 panic("unmount: dangling vnode"); 505 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p); 506 if (mp->mnt_kern_flag & MNTK_MWAIT) 507 wakeup((caddr_t)mp); 508 free((caddr_t)mp, M_MOUNT); 509 return (0); 510 } 511 512 /* 513 * Sync each mounted filesystem. 514 */ 515 #ifndef _SYS_SYSPROTO_H_ 516 struct sync_args { 517 int dummy; 518 }; 519 #endif 520 521 #ifdef DEBUG 522 static int syncprt = 0; 523 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 524 #endif 525 526 /* ARGSUSED */ 527 int 528 sync(p, uap) 529 struct proc *p; 530 struct sync_args *uap; 531 { 532 register struct mount *mp, *nmp; 533 int asyncflag; 534 535 simple_lock(&mountlist_slock); 536 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 537 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 538 nmp = mp->mnt_list.cqe_next; 539 continue; 540 } 541 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 542 asyncflag = mp->mnt_flag & MNT_ASYNC; 543 mp->mnt_flag &= ~MNT_ASYNC; 544 vfs_msync(mp, MNT_NOWAIT); 545 VFS_SYNC(mp, MNT_NOWAIT, 546 ((p != NULL) ? p->p_ucred : NOCRED), p); 547 mp->mnt_flag |= asyncflag; 548 } 549 simple_lock(&mountlist_slock); 550 nmp = mp->mnt_list.cqe_next; 551 vfs_unbusy(mp, p); 552 } 553 simple_unlock(&mountlist_slock); 554 #if 0 555 /* 556 * XXX don't call vfs_bufstats() yet because that routine 557 * was not imported in the Lite2 merge. 558 */ 559 #ifdef DIAGNOSTIC 560 if (syncprt) 561 vfs_bufstats(); 562 #endif /* DIAGNOSTIC */ 563 #endif 564 return (0); 565 } 566 567 /* XXX PRISON: could be per prison flag */ 568 static int prison_quotas; 569 #if 0 570 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 571 #endif 572 573 /* 574 * Change filesystem quotas. 575 */ 576 #ifndef _SYS_SYSPROTO_H_ 577 struct quotactl_args { 578 char *path; 579 int cmd; 580 int uid; 581 caddr_t arg; 582 }; 583 #endif 584 /* ARGSUSED */ 585 int 586 quotactl(p, uap) 587 struct proc *p; 588 register struct quotactl_args /* { 589 syscallarg(char *) path; 590 syscallarg(int) cmd; 591 syscallarg(int) uid; 592 syscallarg(caddr_t) arg; 593 } */ *uap; 594 { 595 register struct mount *mp; 596 int error; 597 struct nameidata nd; 598 599 if (p->p_prison && !prison_quotas) 600 return (EPERM); 601 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 602 if ((error = namei(&nd)) != 0) 603 return (error); 604 mp = nd.ni_vp->v_mount; 605 vrele(nd.ni_vp); 606 return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid), 607 SCARG(uap, arg), p)); 608 } 609 610 /* 611 * Get filesystem statistics. 612 */ 613 #ifndef _SYS_SYSPROTO_H_ 614 struct statfs_args { 615 char *path; 616 struct statfs *buf; 617 }; 618 #endif 619 /* ARGSUSED */ 620 int 621 statfs(p, uap) 622 struct proc *p; 623 register struct statfs_args /* { 624 syscallarg(char *) path; 625 syscallarg(struct statfs *) buf; 626 } */ *uap; 627 { 628 register struct mount *mp; 629 register struct statfs *sp; 630 int error; 631 struct nameidata nd; 632 struct statfs sb; 633 634 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 635 if ((error = namei(&nd)) != 0) 636 return (error); 637 mp = nd.ni_vp->v_mount; 638 sp = &mp->mnt_stat; 639 vrele(nd.ni_vp); 640 error = VFS_STATFS(mp, sp, p); 641 if (error) 642 return (error); 643 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 644 if (suser_xxx(p->p_ucred, 0, 0)) { 645 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 646 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 647 sp = &sb; 648 } 649 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 650 } 651 652 /* 653 * Get filesystem statistics. 654 */ 655 #ifndef _SYS_SYSPROTO_H_ 656 struct fstatfs_args { 657 int fd; 658 struct statfs *buf; 659 }; 660 #endif 661 /* ARGSUSED */ 662 int 663 fstatfs(p, uap) 664 struct proc *p; 665 register struct fstatfs_args /* { 666 syscallarg(int) fd; 667 syscallarg(struct statfs *) buf; 668 } */ *uap; 669 { 670 struct file *fp; 671 struct mount *mp; 672 register struct statfs *sp; 673 int error; 674 struct statfs sb; 675 676 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 677 return (error); 678 mp = ((struct vnode *)fp->f_data)->v_mount; 679 sp = &mp->mnt_stat; 680 error = VFS_STATFS(mp, sp, p); 681 if (error) 682 return (error); 683 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 684 if (suser_xxx(p->p_ucred, 0, 0)) { 685 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 686 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 687 sp = &sb; 688 } 689 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 690 } 691 692 /* 693 * Get statistics on all filesystems. 694 */ 695 #ifndef _SYS_SYSPROTO_H_ 696 struct getfsstat_args { 697 struct statfs *buf; 698 long bufsize; 699 int flags; 700 }; 701 #endif 702 int 703 getfsstat(p, uap) 704 struct proc *p; 705 register struct getfsstat_args /* { 706 syscallarg(struct statfs *) buf; 707 syscallarg(long) bufsize; 708 syscallarg(int) flags; 709 } */ *uap; 710 { 711 register struct mount *mp, *nmp; 712 register struct statfs *sp; 713 caddr_t sfsp; 714 long count, maxcount, error; 715 716 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs); 717 sfsp = (caddr_t)SCARG(uap, buf); 718 count = 0; 719 simple_lock(&mountlist_slock); 720 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 721 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 722 nmp = mp->mnt_list.cqe_next; 723 continue; 724 } 725 if (sfsp && count < maxcount) { 726 sp = &mp->mnt_stat; 727 /* 728 * If MNT_NOWAIT or MNT_LAZY is specified, do not 729 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 730 * overrides MNT_WAIT. 731 */ 732 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 || 733 (SCARG(uap, flags) & MNT_WAIT)) && 734 (error = VFS_STATFS(mp, sp, p))) { 735 simple_lock(&mountlist_slock); 736 nmp = mp->mnt_list.cqe_next; 737 vfs_unbusy(mp, p); 738 continue; 739 } 740 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 741 error = copyout((caddr_t)sp, sfsp, sizeof(*sp)); 742 if (error) { 743 vfs_unbusy(mp, p); 744 return (error); 745 } 746 sfsp += sizeof(*sp); 747 } 748 count++; 749 simple_lock(&mountlist_slock); 750 nmp = mp->mnt_list.cqe_next; 751 vfs_unbusy(mp, p); 752 } 753 simple_unlock(&mountlist_slock); 754 if (sfsp && count > maxcount) 755 p->p_retval[0] = maxcount; 756 else 757 p->p_retval[0] = count; 758 return (0); 759 } 760 761 /* 762 * Change current working directory to a given file descriptor. 763 */ 764 #ifndef _SYS_SYSPROTO_H_ 765 struct fchdir_args { 766 int fd; 767 }; 768 #endif 769 /* ARGSUSED */ 770 int 771 fchdir(p, uap) 772 struct proc *p; 773 struct fchdir_args /* { 774 syscallarg(int) fd; 775 } */ *uap; 776 { 777 register struct filedesc *fdp = p->p_fd; 778 struct vnode *vp, *tdp; 779 struct mount *mp; 780 struct file *fp; 781 int error; 782 783 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 784 return (error); 785 vp = (struct vnode *)fp->f_data; 786 VREF(vp); 787 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 788 if (vp->v_type != VDIR) 789 error = ENOTDIR; 790 else 791 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 792 while (!error && (mp = vp->v_mountedhere) != NULL) { 793 if (vfs_busy(mp, 0, 0, p)) 794 continue; 795 error = VFS_ROOT(mp, &tdp); 796 vfs_unbusy(mp, p); 797 if (error) 798 break; 799 vput(vp); 800 vp = tdp; 801 } 802 if (error) { 803 vput(vp); 804 return (error); 805 } 806 VOP_UNLOCK(vp, 0, p); 807 vrele(fdp->fd_cdir); 808 fdp->fd_cdir = vp; 809 return (0); 810 } 811 812 /* 813 * Change current working directory (``.''). 814 */ 815 #ifndef _SYS_SYSPROTO_H_ 816 struct chdir_args { 817 char *path; 818 }; 819 #endif 820 /* ARGSUSED */ 821 int 822 chdir(p, uap) 823 struct proc *p; 824 struct chdir_args /* { 825 syscallarg(char *) path; 826 } */ *uap; 827 { 828 register struct filedesc *fdp = p->p_fd; 829 int error; 830 struct nameidata nd; 831 832 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 833 SCARG(uap, path), p); 834 if ((error = change_dir(&nd, p)) != 0) 835 return (error); 836 vrele(fdp->fd_cdir); 837 fdp->fd_cdir = nd.ni_vp; 838 return (0); 839 } 840 841 /* 842 * Helper function for raised chroot(2) security function: Refuse if 843 * any filedescriptors are open directories. 844 */ 845 static int 846 chroot_refuse_vdir_fds(fdp) 847 struct filedesc *fdp; 848 { 849 struct vnode *vp; 850 struct file *fp; 851 int error; 852 int fd; 853 854 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 855 error = getvnode(fdp, fd, &fp); 856 if (error) 857 continue; 858 vp = (struct vnode *)fp->f_data; 859 if (vp->v_type != VDIR) 860 continue; 861 return(EPERM); 862 } 863 return (0); 864 } 865 866 /* 867 * This sysctl determines if we will allow a process to chroot(2) if it 868 * has a directory open: 869 * 0: disallowed for all processes. 870 * 1: allowed for processes that were not already chroot(2)'ed. 871 * 2: allowed for all processes. 872 */ 873 874 static int chroot_allow_open_directories = 1; 875 876 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 877 &chroot_allow_open_directories, 0, ""); 878 879 /* 880 * Change notion of root (``/'') directory. 881 */ 882 #ifndef _SYS_SYSPROTO_H_ 883 struct chroot_args { 884 char *path; 885 }; 886 #endif 887 /* ARGSUSED */ 888 int 889 chroot(p, uap) 890 struct proc *p; 891 struct chroot_args /* { 892 syscallarg(char *) path; 893 } */ *uap; 894 { 895 register struct filedesc *fdp = p->p_fd; 896 int error; 897 struct nameidata nd; 898 899 error = suser_xxx(0, p, PRISON_ROOT); 900 if (error) 901 return (error); 902 if (chroot_allow_open_directories == 0 || 903 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) 904 error = chroot_refuse_vdir_fds(fdp); 905 if (error) 906 return (error); 907 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 908 SCARG(uap, path), p); 909 if ((error = change_dir(&nd, p)) != 0) 910 return (error); 911 vrele(fdp->fd_rdir); 912 fdp->fd_rdir = nd.ni_vp; 913 return (0); 914 } 915 916 /* 917 * Common routine for chroot and chdir. 918 */ 919 static int 920 change_dir(ndp, p) 921 register struct nameidata *ndp; 922 struct proc *p; 923 { 924 struct vnode *vp; 925 int error; 926 927 error = namei(ndp); 928 if (error) 929 return (error); 930 vp = ndp->ni_vp; 931 if (vp->v_type != VDIR) 932 error = ENOTDIR; 933 else 934 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 935 if (error) 936 vput(vp); 937 else 938 VOP_UNLOCK(vp, 0, p); 939 return (error); 940 } 941 942 /* 943 * Check permissions, allocate an open file structure, 944 * and call the device open routine if any. 945 */ 946 #ifndef _SYS_SYSPROTO_H_ 947 struct open_args { 948 char *path; 949 int flags; 950 int mode; 951 }; 952 #endif 953 int 954 open(p, uap) 955 struct proc *p; 956 register struct open_args /* { 957 syscallarg(char *) path; 958 syscallarg(int) flags; 959 syscallarg(int) mode; 960 } */ *uap; 961 { 962 register struct filedesc *fdp = p->p_fd; 963 register struct file *fp; 964 register struct vnode *vp; 965 int cmode, flags, oflags; 966 struct file *nfp; 967 int type, indx, error; 968 struct flock lf; 969 struct nameidata nd; 970 971 oflags = SCARG(uap, flags); 972 if ((oflags & O_ACCMODE) == O_ACCMODE) 973 return (EINVAL); 974 flags = FFLAGS(oflags); 975 error = falloc(p, &nfp, &indx); 976 if (error) 977 return (error); 978 fp = nfp; 979 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 980 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 981 p->p_dupfd = -indx - 1; /* XXX check for fdopen */ 982 error = vn_open(&nd, flags, cmode); 983 if (error) { 984 ffree(fp); 985 if ((error == ENODEV || error == ENXIO) && 986 p->p_dupfd >= 0 && /* XXX from fdopen */ 987 (error = 988 dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) { 989 p->p_retval[0] = indx; 990 return (0); 991 } 992 if (error == ERESTART) 993 error = EINTR; 994 fdp->fd_ofiles[indx] = NULL; 995 return (error); 996 } 997 p->p_dupfd = 0; 998 vp = nd.ni_vp; 999 1000 fp->f_data = (caddr_t)vp; 1001 fp->f_flag = flags & FMASK; 1002 fp->f_ops = &vnops; 1003 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); 1004 if (flags & (O_EXLOCK | O_SHLOCK)) { 1005 lf.l_whence = SEEK_SET; 1006 lf.l_start = 0; 1007 lf.l_len = 0; 1008 if (flags & O_EXLOCK) 1009 lf.l_type = F_WRLCK; 1010 else 1011 lf.l_type = F_RDLCK; 1012 type = F_FLOCK; 1013 if ((flags & FNONBLOCK) == 0) 1014 type |= F_WAIT; 1015 VOP_UNLOCK(vp, 0, p); 1016 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 1017 (void) vn_close(vp, fp->f_flag, fp->f_cred, p); 1018 ffree(fp); 1019 fdp->fd_ofiles[indx] = NULL; 1020 return (error); 1021 } 1022 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1023 fp->f_flag |= FHASLOCK; 1024 } 1025 /* assert that vn_open created a backing object if one is needed */ 1026 KASSERT(!vn_canvmio(vp) || vp->v_object != NULL, 1027 ("open: vmio vnode has no backing object after vn_open")); 1028 VOP_UNLOCK(vp, 0, p); 1029 p->p_retval[0] = indx; 1030 return (0); 1031 } 1032 1033 #ifdef COMPAT_43 1034 /* 1035 * Create a file. 1036 */ 1037 #ifndef _SYS_SYSPROTO_H_ 1038 struct ocreat_args { 1039 char *path; 1040 int mode; 1041 }; 1042 #endif 1043 int 1044 ocreat(p, uap) 1045 struct proc *p; 1046 register struct ocreat_args /* { 1047 syscallarg(char *) path; 1048 syscallarg(int) mode; 1049 } */ *uap; 1050 { 1051 struct open_args /* { 1052 syscallarg(char *) path; 1053 syscallarg(int) flags; 1054 syscallarg(int) mode; 1055 } */ nuap; 1056 1057 SCARG(&nuap, path) = SCARG(uap, path); 1058 SCARG(&nuap, mode) = SCARG(uap, mode); 1059 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; 1060 return (open(p, &nuap)); 1061 } 1062 #endif /* COMPAT_43 */ 1063 1064 /* 1065 * Create a special file. 1066 */ 1067 #ifndef _SYS_SYSPROTO_H_ 1068 struct mknod_args { 1069 char *path; 1070 int mode; 1071 int dev; 1072 }; 1073 #endif 1074 /* ARGSUSED */ 1075 int 1076 mknod(p, uap) 1077 struct proc *p; 1078 register struct mknod_args /* { 1079 syscallarg(char *) path; 1080 syscallarg(int) mode; 1081 syscallarg(int) dev; 1082 } */ *uap; 1083 { 1084 register struct vnode *vp; 1085 struct vattr vattr; 1086 int error; 1087 int whiteout = 0; 1088 struct nameidata nd; 1089 1090 switch (SCARG(uap, mode) & S_IFMT) { 1091 case S_IFCHR: 1092 case S_IFBLK: 1093 error = suser(p); 1094 break; 1095 default: 1096 error = suser_xxx(0, p, PRISON_ROOT); 1097 break; 1098 } 1099 if (error) 1100 return (error); 1101 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1102 if ((error = namei(&nd)) != 0) 1103 return (error); 1104 vp = nd.ni_vp; 1105 if (vp != NULL) 1106 error = EEXIST; 1107 else { 1108 VATTR_NULL(&vattr); 1109 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1110 vattr.va_rdev = SCARG(uap, dev); 1111 whiteout = 0; 1112 1113 switch (SCARG(uap, mode) & S_IFMT) { 1114 case S_IFMT: /* used by badsect to flag bad sectors */ 1115 vattr.va_type = VBAD; 1116 break; 1117 case S_IFCHR: 1118 vattr.va_type = VCHR; 1119 break; 1120 case S_IFBLK: 1121 vattr.va_type = VBLK; 1122 break; 1123 case S_IFWHT: 1124 whiteout = 1; 1125 break; 1126 default: 1127 error = EINVAL; 1128 break; 1129 } 1130 } 1131 if (!error) { 1132 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1133 if (whiteout) { 1134 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1135 if (error) 1136 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1137 vput(nd.ni_dvp); 1138 } else { 1139 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1140 &nd.ni_cnd, &vattr); 1141 vput(nd.ni_dvp); 1142 } 1143 } else { 1144 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1145 if (nd.ni_dvp == vp) 1146 vrele(nd.ni_dvp); 1147 else 1148 vput(nd.ni_dvp); 1149 if (vp) 1150 vrele(vp); 1151 } 1152 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); 1153 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); 1154 return (error); 1155 } 1156 1157 /* 1158 * Create a named pipe. 1159 */ 1160 #ifndef _SYS_SYSPROTO_H_ 1161 struct mkfifo_args { 1162 char *path; 1163 int mode; 1164 }; 1165 #endif 1166 /* ARGSUSED */ 1167 int 1168 mkfifo(p, uap) 1169 struct proc *p; 1170 register struct mkfifo_args /* { 1171 syscallarg(char *) path; 1172 syscallarg(int) mode; 1173 } */ *uap; 1174 { 1175 struct vattr vattr; 1176 int error; 1177 struct nameidata nd; 1178 1179 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1180 if ((error = namei(&nd)) != 0) 1181 return (error); 1182 if (nd.ni_vp != NULL) { 1183 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1184 if (nd.ni_dvp == nd.ni_vp) 1185 vrele(nd.ni_dvp); 1186 else 1187 vput(nd.ni_dvp); 1188 vrele(nd.ni_vp); 1189 return (EEXIST); 1190 } 1191 VATTR_NULL(&vattr); 1192 vattr.va_type = VFIFO; 1193 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1194 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1195 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1196 vput(nd.ni_dvp); 1197 return (error); 1198 } 1199 1200 /* 1201 * Make a hard file link. 1202 */ 1203 #ifndef _SYS_SYSPROTO_H_ 1204 struct link_args { 1205 char *path; 1206 char *link; 1207 }; 1208 #endif 1209 /* ARGSUSED */ 1210 int 1211 link(p, uap) 1212 struct proc *p; 1213 register struct link_args /* { 1214 syscallarg(char *) path; 1215 syscallarg(char *) link; 1216 } */ *uap; 1217 { 1218 register struct vnode *vp; 1219 struct nameidata nd; 1220 int error; 1221 1222 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); 1223 if ((error = namei(&nd)) != 0) 1224 return (error); 1225 vp = nd.ni_vp; 1226 if (vp->v_type == VDIR) 1227 error = EPERM; /* POSIX */ 1228 else { 1229 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1230 error = namei(&nd); 1231 if (!error) { 1232 if (nd.ni_vp != NULL) { 1233 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1234 if (nd.ni_vp) 1235 vrele(nd.ni_vp); 1236 error = EEXIST; 1237 } else { 1238 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, 1239 LEASE_WRITE); 1240 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1241 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1242 } 1243 if (nd.ni_dvp == nd.ni_vp) 1244 vrele(nd.ni_dvp); 1245 else 1246 vput(nd.ni_dvp); 1247 } 1248 } 1249 vrele(vp); 1250 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); 1251 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); 1252 return (error); 1253 } 1254 1255 /* 1256 * Make a symbolic link. 1257 */ 1258 #ifndef _SYS_SYSPROTO_H_ 1259 struct symlink_args { 1260 char *path; 1261 char *link; 1262 }; 1263 #endif 1264 /* ARGSUSED */ 1265 int 1266 symlink(p, uap) 1267 struct proc *p; 1268 register struct symlink_args /* { 1269 syscallarg(char *) path; 1270 syscallarg(char *) link; 1271 } */ *uap; 1272 { 1273 struct vattr vattr; 1274 char *path; 1275 int error; 1276 struct nameidata nd; 1277 1278 path = zalloc(namei_zone); 1279 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) 1280 goto out; 1281 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1282 if ((error = namei(&nd)) != 0) 1283 goto out; 1284 if (nd.ni_vp) { 1285 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1286 if (nd.ni_dvp == nd.ni_vp) 1287 vrele(nd.ni_dvp); 1288 else 1289 vput(nd.ni_dvp); 1290 vrele(nd.ni_vp); 1291 error = EEXIST; 1292 goto out; 1293 } 1294 VATTR_NULL(&vattr); 1295 vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; 1296 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1297 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); 1298 vput(nd.ni_dvp); 1299 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); 1300 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); 1301 out: 1302 zfree(namei_zone, path); 1303 return (error); 1304 } 1305 1306 /* 1307 * Delete a whiteout from the filesystem. 1308 */ 1309 /* ARGSUSED */ 1310 int 1311 undelete(p, uap) 1312 struct proc *p; 1313 register struct undelete_args /* { 1314 syscallarg(char *) path; 1315 } */ *uap; 1316 { 1317 int error; 1318 struct nameidata nd; 1319 1320 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE, 1321 SCARG(uap, path), p); 1322 error = namei(&nd); 1323 if (error) 1324 return (error); 1325 1326 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1327 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1328 if (nd.ni_dvp == nd.ni_vp) 1329 vrele(nd.ni_dvp); 1330 else 1331 vput(nd.ni_dvp); 1332 if (nd.ni_vp) 1333 vrele(nd.ni_vp); 1334 return (EEXIST); 1335 } 1336 1337 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1338 if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0) 1339 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1340 vput(nd.ni_dvp); 1341 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); 1342 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); 1343 return (error); 1344 } 1345 1346 /* 1347 * Delete a name from the filesystem. 1348 */ 1349 #ifndef _SYS_SYSPROTO_H_ 1350 struct unlink_args { 1351 char *path; 1352 }; 1353 #endif 1354 /* ARGSUSED */ 1355 int 1356 unlink(p, uap) 1357 struct proc *p; 1358 struct unlink_args /* { 1359 syscallarg(char *) path; 1360 } */ *uap; 1361 { 1362 register struct vnode *vp; 1363 int error; 1364 struct nameidata nd; 1365 1366 NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1367 if ((error = namei(&nd)) != 0) 1368 return (error); 1369 vp = nd.ni_vp; 1370 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1371 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1372 1373 if (vp->v_type == VDIR) 1374 error = EPERM; /* POSIX */ 1375 else { 1376 /* 1377 * The root of a mounted filesystem cannot be deleted. 1378 * 1379 * XXX: can this only be a VDIR case? 1380 */ 1381 if (vp->v_flag & VROOT) 1382 error = EBUSY; 1383 } 1384 1385 if (!error) { 1386 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1387 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1388 } else { 1389 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1390 } 1391 if (nd.ni_dvp == vp) 1392 vrele(nd.ni_dvp); 1393 else 1394 vput(nd.ni_dvp); 1395 if (vp != NULLVP) 1396 vput(vp); 1397 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); 1398 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); 1399 return (error); 1400 } 1401 1402 /* 1403 * Reposition read/write file offset. 1404 */ 1405 #ifndef _SYS_SYSPROTO_H_ 1406 struct lseek_args { 1407 int fd; 1408 int pad; 1409 off_t offset; 1410 int whence; 1411 }; 1412 #endif 1413 int 1414 lseek(p, uap) 1415 struct proc *p; 1416 register struct lseek_args /* { 1417 syscallarg(int) fd; 1418 syscallarg(int) pad; 1419 syscallarg(off_t) offset; 1420 syscallarg(int) whence; 1421 } */ *uap; 1422 { 1423 struct ucred *cred = p->p_ucred; 1424 register struct filedesc *fdp = p->p_fd; 1425 register struct file *fp; 1426 struct vattr vattr; 1427 int error; 1428 1429 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 1430 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) 1431 return (EBADF); 1432 if (fp->f_type != DTYPE_VNODE) 1433 return (ESPIPE); 1434 switch (SCARG(uap, whence)) { 1435 case L_INCR: 1436 fp->f_offset += SCARG(uap, offset); 1437 break; 1438 case L_XTND: 1439 error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p); 1440 if (error) 1441 return (error); 1442 fp->f_offset = SCARG(uap, offset) + vattr.va_size; 1443 break; 1444 case L_SET: 1445 fp->f_offset = SCARG(uap, offset); 1446 break; 1447 default: 1448 return (EINVAL); 1449 } 1450 *(off_t *)(p->p_retval) = fp->f_offset; 1451 return (0); 1452 } 1453 1454 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1455 /* 1456 * Reposition read/write file offset. 1457 */ 1458 #ifndef _SYS_SYSPROTO_H_ 1459 struct olseek_args { 1460 int fd; 1461 long offset; 1462 int whence; 1463 }; 1464 #endif 1465 int 1466 olseek(p, uap) 1467 struct proc *p; 1468 register struct olseek_args /* { 1469 syscallarg(int) fd; 1470 syscallarg(long) offset; 1471 syscallarg(int) whence; 1472 } */ *uap; 1473 { 1474 struct lseek_args /* { 1475 syscallarg(int) fd; 1476 syscallarg(int) pad; 1477 syscallarg(off_t) offset; 1478 syscallarg(int) whence; 1479 } */ nuap; 1480 int error; 1481 1482 SCARG(&nuap, fd) = SCARG(uap, fd); 1483 SCARG(&nuap, offset) = SCARG(uap, offset); 1484 SCARG(&nuap, whence) = SCARG(uap, whence); 1485 error = lseek(p, &nuap); 1486 return (error); 1487 } 1488 #endif /* COMPAT_43 */ 1489 1490 /* 1491 * Check access permissions. 1492 */ 1493 #ifndef _SYS_SYSPROTO_H_ 1494 struct access_args { 1495 char *path; 1496 int flags; 1497 }; 1498 #endif 1499 int 1500 access(p, uap) 1501 struct proc *p; 1502 register struct access_args /* { 1503 syscallarg(char *) path; 1504 syscallarg(int) flags; 1505 } */ *uap; 1506 { 1507 register struct ucred *cred = p->p_ucred; 1508 register struct vnode *vp; 1509 int error, flags, t_gid, t_uid; 1510 struct nameidata nd; 1511 1512 t_uid = cred->cr_uid; 1513 t_gid = cred->cr_groups[0]; 1514 cred->cr_uid = p->p_cred->p_ruid; 1515 cred->cr_groups[0] = p->p_cred->p_rgid; 1516 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1517 SCARG(uap, path), p); 1518 if ((error = namei(&nd)) != 0) 1519 goto out1; 1520 vp = nd.ni_vp; 1521 1522 /* Flags == 0 means only check for existence. */ 1523 if (SCARG(uap, flags)) { 1524 flags = 0; 1525 if (SCARG(uap, flags) & R_OK) 1526 flags |= VREAD; 1527 if (SCARG(uap, flags) & W_OK) 1528 flags |= VWRITE; 1529 if (SCARG(uap, flags) & X_OK) 1530 flags |= VEXEC; 1531 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 1532 error = VOP_ACCESS(vp, flags, cred, p); 1533 } 1534 vput(vp); 1535 out1: 1536 cred->cr_uid = t_uid; 1537 cred->cr_groups[0] = t_gid; 1538 return (error); 1539 } 1540 1541 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1542 /* 1543 * Get file status; this version follows links. 1544 */ 1545 #ifndef _SYS_SYSPROTO_H_ 1546 struct ostat_args { 1547 char *path; 1548 struct ostat *ub; 1549 }; 1550 #endif 1551 /* ARGSUSED */ 1552 int 1553 ostat(p, uap) 1554 struct proc *p; 1555 register struct ostat_args /* { 1556 syscallarg(char *) path; 1557 syscallarg(struct ostat *) ub; 1558 } */ *uap; 1559 { 1560 struct stat sb; 1561 struct ostat osb; 1562 int error; 1563 struct nameidata nd; 1564 1565 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1566 SCARG(uap, path), p); 1567 if ((error = namei(&nd)) != 0) 1568 return (error); 1569 error = vn_stat(nd.ni_vp, &sb, p); 1570 vput(nd.ni_vp); 1571 if (error) 1572 return (error); 1573 cvtstat(&sb, &osb); 1574 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1575 return (error); 1576 } 1577 1578 /* 1579 * Get file status; this version does not follow links. 1580 */ 1581 #ifndef _SYS_SYSPROTO_H_ 1582 struct olstat_args { 1583 char *path; 1584 struct ostat *ub; 1585 }; 1586 #endif 1587 /* ARGSUSED */ 1588 int 1589 olstat(p, uap) 1590 struct proc *p; 1591 register struct olstat_args /* { 1592 syscallarg(char *) path; 1593 syscallarg(struct ostat *) ub; 1594 } */ *uap; 1595 { 1596 struct vnode *vp; 1597 struct stat sb; 1598 struct ostat osb; 1599 int error; 1600 struct nameidata nd; 1601 1602 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1603 SCARG(uap, path), p); 1604 if ((error = namei(&nd)) != 0) 1605 return (error); 1606 vp = nd.ni_vp; 1607 error = vn_stat(vp, &sb, p); 1608 vput(vp); 1609 if (error) 1610 return (error); 1611 cvtstat(&sb, &osb); 1612 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1613 return (error); 1614 } 1615 1616 /* 1617 * Convert from an old to a new stat structure. 1618 */ 1619 void 1620 cvtstat(st, ost) 1621 struct stat *st; 1622 struct ostat *ost; 1623 { 1624 1625 ost->st_dev = st->st_dev; 1626 ost->st_ino = st->st_ino; 1627 ost->st_mode = st->st_mode; 1628 ost->st_nlink = st->st_nlink; 1629 ost->st_uid = st->st_uid; 1630 ost->st_gid = st->st_gid; 1631 ost->st_rdev = st->st_rdev; 1632 if (st->st_size < (quad_t)1 << 32) 1633 ost->st_size = st->st_size; 1634 else 1635 ost->st_size = -2; 1636 ost->st_atime = st->st_atime; 1637 ost->st_mtime = st->st_mtime; 1638 ost->st_ctime = st->st_ctime; 1639 ost->st_blksize = st->st_blksize; 1640 ost->st_blocks = st->st_blocks; 1641 ost->st_flags = st->st_flags; 1642 ost->st_gen = st->st_gen; 1643 } 1644 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1645 1646 /* 1647 * Get file status; this version follows links. 1648 */ 1649 #ifndef _SYS_SYSPROTO_H_ 1650 struct stat_args { 1651 char *path; 1652 struct stat *ub; 1653 }; 1654 #endif 1655 /* ARGSUSED */ 1656 int 1657 stat(p, uap) 1658 struct proc *p; 1659 register struct stat_args /* { 1660 syscallarg(char *) path; 1661 syscallarg(struct stat *) ub; 1662 } */ *uap; 1663 { 1664 struct stat sb; 1665 int error; 1666 struct nameidata nd; 1667 1668 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1669 SCARG(uap, path), p); 1670 if ((error = namei(&nd)) != 0) 1671 return (error); 1672 error = vn_stat(nd.ni_vp, &sb, p); 1673 vput(nd.ni_vp); 1674 if (error) 1675 return (error); 1676 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1677 return (error); 1678 } 1679 1680 /* 1681 * Get file status; this version does not follow links. 1682 */ 1683 #ifndef _SYS_SYSPROTO_H_ 1684 struct lstat_args { 1685 char *path; 1686 struct stat *ub; 1687 }; 1688 #endif 1689 /* ARGSUSED */ 1690 int 1691 lstat(p, uap) 1692 struct proc *p; 1693 register struct lstat_args /* { 1694 syscallarg(char *) path; 1695 syscallarg(struct stat *) ub; 1696 } */ *uap; 1697 { 1698 int error; 1699 struct vnode *vp; 1700 struct stat sb; 1701 struct nameidata nd; 1702 1703 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1704 SCARG(uap, path), p); 1705 if ((error = namei(&nd)) != 0) 1706 return (error); 1707 vp = nd.ni_vp; 1708 error = vn_stat(vp, &sb, p); 1709 vput(vp); 1710 if (error) 1711 return (error); 1712 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1713 return (error); 1714 } 1715 1716 void 1717 cvtnstat(sb, nsb) 1718 struct stat *sb; 1719 struct nstat *nsb; 1720 { 1721 nsb->st_dev = sb->st_dev; 1722 nsb->st_ino = sb->st_ino; 1723 nsb->st_mode = sb->st_mode; 1724 nsb->st_nlink = sb->st_nlink; 1725 nsb->st_uid = sb->st_uid; 1726 nsb->st_gid = sb->st_gid; 1727 nsb->st_rdev = sb->st_rdev; 1728 nsb->st_atimespec = sb->st_atimespec; 1729 nsb->st_mtimespec = sb->st_mtimespec; 1730 nsb->st_ctimespec = sb->st_ctimespec; 1731 nsb->st_size = sb->st_size; 1732 nsb->st_blocks = sb->st_blocks; 1733 nsb->st_blksize = sb->st_blksize; 1734 nsb->st_flags = sb->st_flags; 1735 nsb->st_gen = sb->st_gen; 1736 } 1737 1738 #ifndef _SYS_SYSPROTO_H_ 1739 struct nstat_args { 1740 char *path; 1741 struct nstat *ub; 1742 }; 1743 #endif 1744 /* ARGSUSED */ 1745 int 1746 nstat(p, uap) 1747 struct proc *p; 1748 register struct nstat_args /* { 1749 syscallarg(char *) path; 1750 syscallarg(struct nstat *) ub; 1751 } */ *uap; 1752 { 1753 struct stat sb; 1754 struct nstat nsb; 1755 int error; 1756 struct nameidata nd; 1757 1758 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1759 SCARG(uap, path), p); 1760 if ((error = namei(&nd)) != 0) 1761 return (error); 1762 error = vn_stat(nd.ni_vp, &sb, p); 1763 vput(nd.ni_vp); 1764 if (error) 1765 return (error); 1766 cvtnstat(&sb, &nsb); 1767 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1768 return (error); 1769 } 1770 1771 /* 1772 * Get file status; this version does not follow links. 1773 */ 1774 #ifndef _SYS_SYSPROTO_H_ 1775 struct lstat_args { 1776 char *path; 1777 struct stat *ub; 1778 }; 1779 #endif 1780 /* ARGSUSED */ 1781 int 1782 nlstat(p, uap) 1783 struct proc *p; 1784 register struct nlstat_args /* { 1785 syscallarg(char *) path; 1786 syscallarg(struct nstat *) ub; 1787 } */ *uap; 1788 { 1789 int error; 1790 struct vnode *vp; 1791 struct stat sb; 1792 struct nstat nsb; 1793 struct nameidata nd; 1794 1795 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1796 SCARG(uap, path), p); 1797 if ((error = namei(&nd)) != 0) 1798 return (error); 1799 vp = nd.ni_vp; 1800 error = vn_stat(vp, &sb, p); 1801 vput(vp); 1802 if (error) 1803 return (error); 1804 cvtnstat(&sb, &nsb); 1805 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1806 return (error); 1807 } 1808 1809 /* 1810 * Get configurable pathname variables. 1811 */ 1812 #ifndef _SYS_SYSPROTO_H_ 1813 struct pathconf_args { 1814 char *path; 1815 int name; 1816 }; 1817 #endif 1818 /* ARGSUSED */ 1819 int 1820 pathconf(p, uap) 1821 struct proc *p; 1822 register struct pathconf_args /* { 1823 syscallarg(char *) path; 1824 syscallarg(int) name; 1825 } */ *uap; 1826 { 1827 int error; 1828 struct nameidata nd; 1829 1830 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1831 SCARG(uap, path), p); 1832 if ((error = namei(&nd)) != 0) 1833 return (error); 1834 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), p->p_retval); 1835 vput(nd.ni_vp); 1836 return (error); 1837 } 1838 1839 /* 1840 * Return target name of a symbolic link. 1841 */ 1842 #ifndef _SYS_SYSPROTO_H_ 1843 struct readlink_args { 1844 char *path; 1845 char *buf; 1846 int count; 1847 }; 1848 #endif 1849 /* ARGSUSED */ 1850 int 1851 readlink(p, uap) 1852 struct proc *p; 1853 register struct readlink_args /* { 1854 syscallarg(char *) path; 1855 syscallarg(char *) buf; 1856 syscallarg(int) count; 1857 } */ *uap; 1858 { 1859 register struct vnode *vp; 1860 struct iovec aiov; 1861 struct uio auio; 1862 int error; 1863 struct nameidata nd; 1864 1865 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1866 SCARG(uap, path), p); 1867 if ((error = namei(&nd)) != 0) 1868 return (error); 1869 vp = nd.ni_vp; 1870 if (vp->v_type != VLNK) 1871 error = EINVAL; 1872 else { 1873 aiov.iov_base = SCARG(uap, buf); 1874 aiov.iov_len = SCARG(uap, count); 1875 auio.uio_iov = &aiov; 1876 auio.uio_iovcnt = 1; 1877 auio.uio_offset = 0; 1878 auio.uio_rw = UIO_READ; 1879 auio.uio_segflg = UIO_USERSPACE; 1880 auio.uio_procp = p; 1881 auio.uio_resid = SCARG(uap, count); 1882 error = VOP_READLINK(vp, &auio, p->p_ucred); 1883 } 1884 vput(vp); 1885 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 1886 return (error); 1887 } 1888 1889 static int 1890 setfflags(p, vp, flags) 1891 struct proc *p; 1892 struct vnode *vp; 1893 int flags; 1894 { 1895 int error; 1896 struct vattr vattr; 1897 1898 /* 1899 * Prevent non-root users from setting flags on devices. When 1900 * a device is reused, users can retain ownership of the device 1901 * if they are allowed to set flags and programs assume that 1902 * chown can't fail when done as root. 1903 */ 1904 if ((vp->v_type == VCHR || vp->v_type == VBLK) && 1905 ((error = suser_xxx(p->p_ucred, p, PRISON_ROOT)) != 0)) 1906 return (error); 1907 1908 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1909 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1910 VATTR_NULL(&vattr); 1911 vattr.va_flags = flags; 1912 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1913 VOP_UNLOCK(vp, 0, p); 1914 return (error); 1915 } 1916 1917 /* 1918 * Change flags of a file given a path name. 1919 */ 1920 #ifndef _SYS_SYSPROTO_H_ 1921 struct chflags_args { 1922 char *path; 1923 int flags; 1924 }; 1925 #endif 1926 /* ARGSUSED */ 1927 int 1928 chflags(p, uap) 1929 struct proc *p; 1930 register struct chflags_args /* { 1931 syscallarg(char *) path; 1932 syscallarg(int) flags; 1933 } */ *uap; 1934 { 1935 int error; 1936 struct nameidata nd; 1937 1938 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 1939 if ((error = namei(&nd)) != 0) 1940 return (error); 1941 error = setfflags(p, nd.ni_vp, SCARG(uap, flags)); 1942 vrele(nd.ni_vp); 1943 return error; 1944 } 1945 1946 /* 1947 * Change flags of a file given a file descriptor. 1948 */ 1949 #ifndef _SYS_SYSPROTO_H_ 1950 struct fchflags_args { 1951 int fd; 1952 int flags; 1953 }; 1954 #endif 1955 /* ARGSUSED */ 1956 int 1957 fchflags(p, uap) 1958 struct proc *p; 1959 register struct fchflags_args /* { 1960 syscallarg(int) fd; 1961 syscallarg(int) flags; 1962 } */ *uap; 1963 { 1964 struct file *fp; 1965 int error; 1966 1967 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1968 return (error); 1969 return setfflags(p, (struct vnode *) fp->f_data, SCARG(uap, flags)); 1970 } 1971 1972 static int 1973 setfmode(p, vp, mode) 1974 struct proc *p; 1975 struct vnode *vp; 1976 int mode; 1977 { 1978 int error; 1979 struct vattr vattr; 1980 1981 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1982 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1983 VATTR_NULL(&vattr); 1984 vattr.va_mode = mode & ALLPERMS; 1985 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1986 VOP_UNLOCK(vp, 0, p); 1987 return error; 1988 } 1989 1990 /* 1991 * Change mode of a file given path name. 1992 */ 1993 #ifndef _SYS_SYSPROTO_H_ 1994 struct chmod_args { 1995 char *path; 1996 int mode; 1997 }; 1998 #endif 1999 /* ARGSUSED */ 2000 int 2001 chmod(p, uap) 2002 struct proc *p; 2003 register struct chmod_args /* { 2004 syscallarg(char *) path; 2005 syscallarg(int) mode; 2006 } */ *uap; 2007 { 2008 int error; 2009 struct nameidata nd; 2010 2011 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2012 if ((error = namei(&nd)) != 0) 2013 return (error); 2014 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2015 vrele(nd.ni_vp); 2016 return error; 2017 } 2018 2019 /* 2020 * Change mode of a file given path name (don't follow links.) 2021 */ 2022 #ifndef _SYS_SYSPROTO_H_ 2023 struct lchmod_args { 2024 char *path; 2025 int mode; 2026 }; 2027 #endif 2028 /* ARGSUSED */ 2029 int 2030 lchmod(p, uap) 2031 struct proc *p; 2032 register struct lchmod_args /* { 2033 syscallarg(char *) path; 2034 syscallarg(int) mode; 2035 } */ *uap; 2036 { 2037 int error; 2038 struct nameidata nd; 2039 2040 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2041 if ((error = namei(&nd)) != 0) 2042 return (error); 2043 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2044 vrele(nd.ni_vp); 2045 return error; 2046 } 2047 2048 /* 2049 * Change mode of a file given a file descriptor. 2050 */ 2051 #ifndef _SYS_SYSPROTO_H_ 2052 struct fchmod_args { 2053 int fd; 2054 int mode; 2055 }; 2056 #endif 2057 /* ARGSUSED */ 2058 int 2059 fchmod(p, uap) 2060 struct proc *p; 2061 register struct fchmod_args /* { 2062 syscallarg(int) fd; 2063 syscallarg(int) mode; 2064 } */ *uap; 2065 { 2066 struct file *fp; 2067 int error; 2068 2069 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2070 return (error); 2071 return setfmode(p, (struct vnode *)fp->f_data, SCARG(uap, mode)); 2072 } 2073 2074 static int 2075 setfown(p, vp, uid, gid) 2076 struct proc *p; 2077 struct vnode *vp; 2078 uid_t uid; 2079 gid_t gid; 2080 { 2081 int error; 2082 struct vattr vattr; 2083 2084 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2085 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2086 VATTR_NULL(&vattr); 2087 vattr.va_uid = uid; 2088 vattr.va_gid = gid; 2089 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2090 VOP_UNLOCK(vp, 0, p); 2091 return error; 2092 } 2093 2094 /* 2095 * Set ownership given a path name. 2096 */ 2097 #ifndef _SYS_SYSPROTO_H_ 2098 struct chown_args { 2099 char *path; 2100 int uid; 2101 int gid; 2102 }; 2103 #endif 2104 /* ARGSUSED */ 2105 int 2106 chown(p, uap) 2107 struct proc *p; 2108 register struct chown_args /* { 2109 syscallarg(char *) path; 2110 syscallarg(int) uid; 2111 syscallarg(int) gid; 2112 } */ *uap; 2113 { 2114 int error; 2115 struct nameidata nd; 2116 2117 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2118 if ((error = namei(&nd)) != 0) 2119 return (error); 2120 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2121 vrele(nd.ni_vp); 2122 2123 return (error); 2124 } 2125 2126 /* 2127 * Set ownership given a path name, do not cross symlinks. 2128 */ 2129 #ifndef _SYS_SYSPROTO_H_ 2130 struct lchown_args { 2131 char *path; 2132 int uid; 2133 int gid; 2134 }; 2135 #endif 2136 /* ARGSUSED */ 2137 int 2138 lchown(p, uap) 2139 struct proc *p; 2140 register struct lchown_args /* { 2141 syscallarg(char *) path; 2142 syscallarg(int) uid; 2143 syscallarg(int) gid; 2144 } */ *uap; 2145 { 2146 int error; 2147 struct nameidata nd; 2148 2149 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2150 if ((error = namei(&nd)) != 0) 2151 return (error); 2152 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2153 vrele(nd.ni_vp); 2154 return (error); 2155 } 2156 2157 /* 2158 * Set ownership given a file descriptor. 2159 */ 2160 #ifndef _SYS_SYSPROTO_H_ 2161 struct fchown_args { 2162 int fd; 2163 int uid; 2164 int gid; 2165 }; 2166 #endif 2167 /* ARGSUSED */ 2168 int 2169 fchown(p, uap) 2170 struct proc *p; 2171 register struct fchown_args /* { 2172 syscallarg(int) fd; 2173 syscallarg(int) uid; 2174 syscallarg(int) gid; 2175 } */ *uap; 2176 { 2177 struct file *fp; 2178 int error; 2179 2180 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2181 return (error); 2182 return setfown(p, (struct vnode *)fp->f_data, 2183 SCARG(uap, uid), SCARG(uap, gid)); 2184 } 2185 2186 static int 2187 getutimes(usrtvp, tsp) 2188 const struct timeval *usrtvp; 2189 struct timespec *tsp; 2190 { 2191 struct timeval tv[2]; 2192 int error; 2193 2194 if (usrtvp == NULL) { 2195 microtime(&tv[0]); 2196 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2197 tsp[1] = tsp[0]; 2198 } else { 2199 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0) 2200 return (error); 2201 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2202 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]); 2203 } 2204 return 0; 2205 } 2206 2207 static int 2208 setutimes(p, vp, ts, nullflag) 2209 struct proc *p; 2210 struct vnode *vp; 2211 const struct timespec *ts; 2212 int nullflag; 2213 { 2214 int error; 2215 struct vattr vattr; 2216 2217 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2218 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2219 VATTR_NULL(&vattr); 2220 vattr.va_atime = ts[0]; 2221 vattr.va_mtime = ts[1]; 2222 if (nullflag) 2223 vattr.va_vaflags |= VA_UTIMES_NULL; 2224 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2225 VOP_UNLOCK(vp, 0, p); 2226 return error; 2227 } 2228 2229 /* 2230 * Set the access and modification times of a file. 2231 */ 2232 #ifndef _SYS_SYSPROTO_H_ 2233 struct utimes_args { 2234 char *path; 2235 struct timeval *tptr; 2236 }; 2237 #endif 2238 /* ARGSUSED */ 2239 int 2240 utimes(p, uap) 2241 struct proc *p; 2242 register struct utimes_args /* { 2243 syscallarg(char *) path; 2244 syscallarg(struct timeval *) tptr; 2245 } */ *uap; 2246 { 2247 struct timespec ts[2]; 2248 struct timeval *usrtvp; 2249 int error; 2250 struct nameidata nd; 2251 2252 usrtvp = SCARG(uap, tptr); 2253 if ((error = getutimes(usrtvp, ts)) != 0) 2254 return (error); 2255 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2256 if ((error = namei(&nd)) != 0) 2257 return (error); 2258 error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL); 2259 vrele(nd.ni_vp); 2260 return (error); 2261 } 2262 2263 /* 2264 * Set the access and modification times of a file. 2265 */ 2266 #ifndef _SYS_SYSPROTO_H_ 2267 struct lutimes_args { 2268 char *path; 2269 struct timeval *tptr; 2270 }; 2271 #endif 2272 /* ARGSUSED */ 2273 int 2274 lutimes(p, uap) 2275 struct proc *p; 2276 register struct lutimes_args /* { 2277 syscallarg(char *) path; 2278 syscallarg(struct timeval *) tptr; 2279 } */ *uap; 2280 { 2281 struct timespec ts[2]; 2282 struct timeval *usrtvp; 2283 int error; 2284 struct nameidata nd; 2285 2286 usrtvp = SCARG(uap, tptr); 2287 if ((error = getutimes(usrtvp, ts)) != 0) 2288 return (error); 2289 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2290 if ((error = namei(&nd)) != 0) 2291 return (error); 2292 error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL); 2293 vrele(nd.ni_vp); 2294 return (error); 2295 } 2296 2297 /* 2298 * Set the access and modification times of a file. 2299 */ 2300 #ifndef _SYS_SYSPROTO_H_ 2301 struct futimes_args { 2302 int fd; 2303 struct timeval *tptr; 2304 }; 2305 #endif 2306 /* ARGSUSED */ 2307 int 2308 futimes(p, uap) 2309 struct proc *p; 2310 register struct futimes_args /* { 2311 syscallarg(int ) fd; 2312 syscallarg(struct timeval *) tptr; 2313 } */ *uap; 2314 { 2315 struct timespec ts[2]; 2316 struct file *fp; 2317 struct timeval *usrtvp; 2318 int error; 2319 2320 usrtvp = SCARG(uap, tptr); 2321 if ((error = getutimes(usrtvp, ts)) != 0) 2322 return (error); 2323 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2324 return (error); 2325 return setutimes(p, (struct vnode *)fp->f_data, ts, usrtvp == NULL); 2326 } 2327 2328 /* 2329 * Truncate a file given its path name. 2330 */ 2331 #ifndef _SYS_SYSPROTO_H_ 2332 struct truncate_args { 2333 char *path; 2334 int pad; 2335 off_t length; 2336 }; 2337 #endif 2338 /* ARGSUSED */ 2339 int 2340 truncate(p, uap) 2341 struct proc *p; 2342 register struct truncate_args /* { 2343 syscallarg(char *) path; 2344 syscallarg(int) pad; 2345 syscallarg(off_t) length; 2346 } */ *uap; 2347 { 2348 register struct vnode *vp; 2349 struct vattr vattr; 2350 int error; 2351 struct nameidata nd; 2352 2353 if (uap->length < 0) 2354 return(EINVAL); 2355 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2356 if ((error = namei(&nd)) != 0) 2357 return (error); 2358 vp = nd.ni_vp; 2359 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2360 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2361 if (vp->v_type == VDIR) 2362 error = EISDIR; 2363 else if ((error = vn_writechk(vp)) == 0 && 2364 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) { 2365 VATTR_NULL(&vattr); 2366 vattr.va_size = SCARG(uap, length); 2367 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2368 } 2369 vput(vp); 2370 return (error); 2371 } 2372 2373 /* 2374 * Truncate a file given a file descriptor. 2375 */ 2376 #ifndef _SYS_SYSPROTO_H_ 2377 struct ftruncate_args { 2378 int fd; 2379 int pad; 2380 off_t length; 2381 }; 2382 #endif 2383 /* ARGSUSED */ 2384 int 2385 ftruncate(p, uap) 2386 struct proc *p; 2387 register struct ftruncate_args /* { 2388 syscallarg(int) fd; 2389 syscallarg(int) pad; 2390 syscallarg(off_t) length; 2391 } */ *uap; 2392 { 2393 struct vattr vattr; 2394 struct vnode *vp; 2395 struct file *fp; 2396 int error; 2397 2398 if (uap->length < 0) 2399 return(EINVAL); 2400 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2401 return (error); 2402 if ((fp->f_flag & FWRITE) == 0) 2403 return (EINVAL); 2404 vp = (struct vnode *)fp->f_data; 2405 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2406 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2407 if (vp->v_type == VDIR) 2408 error = EISDIR; 2409 else if ((error = vn_writechk(vp)) == 0) { 2410 VATTR_NULL(&vattr); 2411 vattr.va_size = SCARG(uap, length); 2412 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 2413 } 2414 VOP_UNLOCK(vp, 0, p); 2415 return (error); 2416 } 2417 2418 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 2419 /* 2420 * Truncate a file given its path name. 2421 */ 2422 #ifndef _SYS_SYSPROTO_H_ 2423 struct otruncate_args { 2424 char *path; 2425 long length; 2426 }; 2427 #endif 2428 /* ARGSUSED */ 2429 int 2430 otruncate(p, uap) 2431 struct proc *p; 2432 register struct otruncate_args /* { 2433 syscallarg(char *) path; 2434 syscallarg(long) length; 2435 } */ *uap; 2436 { 2437 struct truncate_args /* { 2438 syscallarg(char *) path; 2439 syscallarg(int) pad; 2440 syscallarg(off_t) length; 2441 } */ nuap; 2442 2443 SCARG(&nuap, path) = SCARG(uap, path); 2444 SCARG(&nuap, length) = SCARG(uap, length); 2445 return (truncate(p, &nuap)); 2446 } 2447 2448 /* 2449 * Truncate a file given a file descriptor. 2450 */ 2451 #ifndef _SYS_SYSPROTO_H_ 2452 struct oftruncate_args { 2453 int fd; 2454 long length; 2455 }; 2456 #endif 2457 /* ARGSUSED */ 2458 int 2459 oftruncate(p, uap) 2460 struct proc *p; 2461 register struct oftruncate_args /* { 2462 syscallarg(int) fd; 2463 syscallarg(long) length; 2464 } */ *uap; 2465 { 2466 struct ftruncate_args /* { 2467 syscallarg(int) fd; 2468 syscallarg(int) pad; 2469 syscallarg(off_t) length; 2470 } */ nuap; 2471 2472 SCARG(&nuap, fd) = SCARG(uap, fd); 2473 SCARG(&nuap, length) = SCARG(uap, length); 2474 return (ftruncate(p, &nuap)); 2475 } 2476 #endif /* COMPAT_43 || COMPAT_SUNOS */ 2477 2478 /* 2479 * Sync an open file. 2480 */ 2481 #ifndef _SYS_SYSPROTO_H_ 2482 struct fsync_args { 2483 int fd; 2484 }; 2485 #endif 2486 /* ARGSUSED */ 2487 int 2488 fsync(p, uap) 2489 struct proc *p; 2490 struct fsync_args /* { 2491 syscallarg(int) fd; 2492 } */ *uap; 2493 { 2494 register struct vnode *vp; 2495 struct file *fp; 2496 int error; 2497 2498 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2499 return (error); 2500 vp = (struct vnode *)fp->f_data; 2501 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2502 if (vp->v_object) 2503 vm_object_page_clean(vp->v_object, 0, 0, 0); 2504 if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 && 2505 vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && 2506 bioops.io_fsync) 2507 error = (*bioops.io_fsync)(vp); 2508 VOP_UNLOCK(vp, 0, p); 2509 return (error); 2510 } 2511 2512 /* 2513 * Rename files. Source and destination must either both be directories, 2514 * or both not be directories. If target is a directory, it must be empty. 2515 */ 2516 #ifndef _SYS_SYSPROTO_H_ 2517 struct rename_args { 2518 char *from; 2519 char *to; 2520 }; 2521 #endif 2522 /* ARGSUSED */ 2523 int 2524 rename(p, uap) 2525 struct proc *p; 2526 register struct rename_args /* { 2527 syscallarg(char *) from; 2528 syscallarg(char *) to; 2529 } */ *uap; 2530 { 2531 register struct vnode *tvp, *fvp, *tdvp; 2532 struct nameidata fromnd, tond; 2533 int error; 2534 2535 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 2536 SCARG(uap, from), p); 2537 if ((error = namei(&fromnd)) != 0) 2538 return (error); 2539 fvp = fromnd.ni_vp; 2540 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ, 2541 UIO_USERSPACE, SCARG(uap, to), p); 2542 if (fromnd.ni_vp->v_type == VDIR) 2543 tond.ni_cnd.cn_flags |= WILLBEDIR; 2544 if ((error = namei(&tond)) != 0) { 2545 /* Translate error code for rename("dir1", "dir2/."). */ 2546 if (error == EISDIR && fvp->v_type == VDIR) 2547 error = EINVAL; 2548 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2549 vrele(fromnd.ni_dvp); 2550 vrele(fvp); 2551 goto out1; 2552 } 2553 tdvp = tond.ni_dvp; 2554 tvp = tond.ni_vp; 2555 if (tvp != NULL) { 2556 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2557 error = ENOTDIR; 2558 goto out; 2559 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2560 error = EISDIR; 2561 goto out; 2562 } 2563 } 2564 if (fvp == tdvp) 2565 error = EINVAL; 2566 /* 2567 * If source is the same as the destination (that is the 2568 * same inode number with the same name in the same directory), 2569 * then there is nothing to do. 2570 */ 2571 if (fvp == tvp && fromnd.ni_dvp == tdvp && 2572 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 2573 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 2574 fromnd.ni_cnd.cn_namelen)) 2575 error = -1; 2576 out: 2577 if (!error) { 2578 VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE); 2579 if (fromnd.ni_dvp != tdvp) { 2580 VOP_LEASE(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2581 } 2582 if (tvp) { 2583 VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE); 2584 } 2585 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 2586 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 2587 } else { 2588 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 2589 if (tdvp == tvp) 2590 vrele(tdvp); 2591 else 2592 vput(tdvp); 2593 if (tvp) 2594 vput(tvp); 2595 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2596 vrele(fromnd.ni_dvp); 2597 vrele(fvp); 2598 } 2599 vrele(tond.ni_startdir); 2600 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); 2601 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); 2602 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); 2603 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); 2604 zfree(namei_zone, tond.ni_cnd.cn_pnbuf); 2605 out1: 2606 if (fromnd.ni_startdir) 2607 vrele(fromnd.ni_startdir); 2608 zfree(namei_zone, fromnd.ni_cnd.cn_pnbuf); 2609 if (error == -1) 2610 return (0); 2611 return (error); 2612 } 2613 2614 /* 2615 * Make a directory file. 2616 */ 2617 #ifndef _SYS_SYSPROTO_H_ 2618 struct mkdir_args { 2619 char *path; 2620 int mode; 2621 }; 2622 #endif 2623 /* ARGSUSED */ 2624 int 2625 mkdir(p, uap) 2626 struct proc *p; 2627 register struct mkdir_args /* { 2628 syscallarg(char *) path; 2629 syscallarg(int) mode; 2630 } */ *uap; 2631 { 2632 register struct vnode *vp; 2633 struct vattr vattr; 2634 int error; 2635 struct nameidata nd; 2636 2637 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 2638 nd.ni_cnd.cn_flags |= WILLBEDIR; 2639 if ((error = namei(&nd)) != 0) 2640 return (error); 2641 vp = nd.ni_vp; 2642 if (vp != NULL) { 2643 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2644 if (nd.ni_dvp == vp) 2645 vrele(nd.ni_dvp); 2646 else 2647 vput(nd.ni_dvp); 2648 vrele(vp); 2649 return (EEXIST); 2650 } 2651 VATTR_NULL(&vattr); 2652 vattr.va_type = VDIR; 2653 vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; 2654 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2655 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 2656 vput(nd.ni_dvp); 2657 if (!error) 2658 vput(nd.ni_vp); 2659 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); 2660 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); 2661 return (error); 2662 } 2663 2664 /* 2665 * Remove a directory file. 2666 */ 2667 #ifndef _SYS_SYSPROTO_H_ 2668 struct rmdir_args { 2669 char *path; 2670 }; 2671 #endif 2672 /* ARGSUSED */ 2673 int 2674 rmdir(p, uap) 2675 struct proc *p; 2676 struct rmdir_args /* { 2677 syscallarg(char *) path; 2678 } */ *uap; 2679 { 2680 register struct vnode *vp; 2681 int error; 2682 struct nameidata nd; 2683 2684 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, 2685 SCARG(uap, path), p); 2686 if ((error = namei(&nd)) != 0) 2687 return (error); 2688 vp = nd.ni_vp; 2689 if (vp->v_type != VDIR) { 2690 error = ENOTDIR; 2691 goto out; 2692 } 2693 /* 2694 * No rmdir "." please. 2695 */ 2696 if (nd.ni_dvp == vp) { 2697 error = EINVAL; 2698 goto out; 2699 } 2700 /* 2701 * The root of a mounted filesystem cannot be deleted. 2702 */ 2703 if (vp->v_flag & VROOT) 2704 error = EBUSY; 2705 out: 2706 if (!error) { 2707 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2708 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2709 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 2710 } else { 2711 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2712 } 2713 if (nd.ni_dvp == vp) 2714 vrele(nd.ni_dvp); 2715 else 2716 vput(nd.ni_dvp); 2717 if (vp != NULLVP) 2718 vput(vp); 2719 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); 2720 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); 2721 return (error); 2722 } 2723 2724 #ifdef COMPAT_43 2725 /* 2726 * Read a block of directory entries in a file system independent format. 2727 */ 2728 #ifndef _SYS_SYSPROTO_H_ 2729 struct ogetdirentries_args { 2730 int fd; 2731 char *buf; 2732 u_int count; 2733 long *basep; 2734 }; 2735 #endif 2736 int 2737 ogetdirentries(p, uap) 2738 struct proc *p; 2739 register struct ogetdirentries_args /* { 2740 syscallarg(int) fd; 2741 syscallarg(char *) buf; 2742 syscallarg(u_int) count; 2743 syscallarg(long *) basep; 2744 } */ *uap; 2745 { 2746 struct vnode *vp; 2747 struct file *fp; 2748 struct uio auio, kuio; 2749 struct iovec aiov, kiov; 2750 struct dirent *dp, *edp; 2751 caddr_t dirbuf; 2752 int error, eofflag, readcnt; 2753 long loff; 2754 2755 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2756 return (error); 2757 if ((fp->f_flag & FREAD) == 0) 2758 return (EBADF); 2759 vp = (struct vnode *)fp->f_data; 2760 unionread: 2761 if (vp->v_type != VDIR) 2762 return (EINVAL); 2763 aiov.iov_base = SCARG(uap, buf); 2764 aiov.iov_len = SCARG(uap, count); 2765 auio.uio_iov = &aiov; 2766 auio.uio_iovcnt = 1; 2767 auio.uio_rw = UIO_READ; 2768 auio.uio_segflg = UIO_USERSPACE; 2769 auio.uio_procp = p; 2770 auio.uio_resid = SCARG(uap, count); 2771 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2772 loff = auio.uio_offset = fp->f_offset; 2773 # if (BYTE_ORDER != LITTLE_ENDIAN) 2774 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 2775 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 2776 NULL, NULL); 2777 fp->f_offset = auio.uio_offset; 2778 } else 2779 # endif 2780 { 2781 kuio = auio; 2782 kuio.uio_iov = &kiov; 2783 kuio.uio_segflg = UIO_SYSSPACE; 2784 kiov.iov_len = SCARG(uap, count); 2785 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK); 2786 kiov.iov_base = dirbuf; 2787 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 2788 NULL, NULL); 2789 fp->f_offset = kuio.uio_offset; 2790 if (error == 0) { 2791 readcnt = SCARG(uap, count) - kuio.uio_resid; 2792 edp = (struct dirent *)&dirbuf[readcnt]; 2793 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 2794 # if (BYTE_ORDER == LITTLE_ENDIAN) 2795 /* 2796 * The expected low byte of 2797 * dp->d_namlen is our dp->d_type. 2798 * The high MBZ byte of dp->d_namlen 2799 * is our dp->d_namlen. 2800 */ 2801 dp->d_type = dp->d_namlen; 2802 dp->d_namlen = 0; 2803 # else 2804 /* 2805 * The dp->d_type is the high byte 2806 * of the expected dp->d_namlen, 2807 * so must be zero'ed. 2808 */ 2809 dp->d_type = 0; 2810 # endif 2811 if (dp->d_reclen > 0) { 2812 dp = (struct dirent *) 2813 ((char *)dp + dp->d_reclen); 2814 } else { 2815 error = EIO; 2816 break; 2817 } 2818 } 2819 if (dp >= edp) 2820 error = uiomove(dirbuf, readcnt, &auio); 2821 } 2822 FREE(dirbuf, M_TEMP); 2823 } 2824 VOP_UNLOCK(vp, 0, p); 2825 if (error) 2826 return (error); 2827 if (SCARG(uap, count) == auio.uio_resid) { 2828 if (union_dircheckp) { 2829 error = union_dircheckp(p, &vp, fp); 2830 if (error == -1) 2831 goto unionread; 2832 if (error) 2833 return (error); 2834 } 2835 if ((vp->v_flag & VROOT) && 2836 (vp->v_mount->mnt_flag & MNT_UNION)) { 2837 struct vnode *tvp = vp; 2838 vp = vp->v_mount->mnt_vnodecovered; 2839 VREF(vp); 2840 fp->f_data = (caddr_t) vp; 2841 fp->f_offset = 0; 2842 vrele(tvp); 2843 goto unionread; 2844 } 2845 } 2846 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2847 sizeof(long)); 2848 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2849 return (error); 2850 } 2851 #endif /* COMPAT_43 */ 2852 2853 /* 2854 * Read a block of directory entries in a file system independent format. 2855 */ 2856 #ifndef _SYS_SYSPROTO_H_ 2857 struct getdirentries_args { 2858 int fd; 2859 char *buf; 2860 u_int count; 2861 long *basep; 2862 }; 2863 #endif 2864 int 2865 getdirentries(p, uap) 2866 struct proc *p; 2867 register struct getdirentries_args /* { 2868 syscallarg(int) fd; 2869 syscallarg(char *) buf; 2870 syscallarg(u_int) count; 2871 syscallarg(long *) basep; 2872 } */ *uap; 2873 { 2874 struct vnode *vp; 2875 struct file *fp; 2876 struct uio auio; 2877 struct iovec aiov; 2878 long loff; 2879 int error, eofflag; 2880 2881 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2882 return (error); 2883 if ((fp->f_flag & FREAD) == 0) 2884 return (EBADF); 2885 vp = (struct vnode *)fp->f_data; 2886 unionread: 2887 if (vp->v_type != VDIR) 2888 return (EINVAL); 2889 aiov.iov_base = SCARG(uap, buf); 2890 aiov.iov_len = SCARG(uap, count); 2891 auio.uio_iov = &aiov; 2892 auio.uio_iovcnt = 1; 2893 auio.uio_rw = UIO_READ; 2894 auio.uio_segflg = UIO_USERSPACE; 2895 auio.uio_procp = p; 2896 auio.uio_resid = SCARG(uap, count); 2897 /* vn_lock(vp, LK_SHARED | LK_RETRY, p); */ 2898 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2899 loff = auio.uio_offset = fp->f_offset; 2900 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 2901 fp->f_offset = auio.uio_offset; 2902 VOP_UNLOCK(vp, 0, p); 2903 if (error) 2904 return (error); 2905 if (SCARG(uap, count) == auio.uio_resid) { 2906 if (union_dircheckp) { 2907 error = union_dircheckp(p, &vp, fp); 2908 if (error == -1) 2909 goto unionread; 2910 if (error) 2911 return (error); 2912 } 2913 if ((vp->v_flag & VROOT) && 2914 (vp->v_mount->mnt_flag & MNT_UNION)) { 2915 struct vnode *tvp = vp; 2916 vp = vp->v_mount->mnt_vnodecovered; 2917 VREF(vp); 2918 fp->f_data = (caddr_t) vp; 2919 fp->f_offset = 0; 2920 vrele(tvp); 2921 goto unionread; 2922 } 2923 } 2924 if (SCARG(uap, basep) != NULL) { 2925 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2926 sizeof(long)); 2927 } 2928 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2929 return (error); 2930 } 2931 #ifndef _SYS_SYSPROTO_H_ 2932 struct getdents_args { 2933 int fd; 2934 char *buf; 2935 size_t count; 2936 }; 2937 #endif 2938 int 2939 getdents(p, uap) 2940 struct proc *p; 2941 register struct getdents_args /* { 2942 syscallarg(int) fd; 2943 syscallarg(char *) buf; 2944 syscallarg(u_int) count; 2945 } */ *uap; 2946 { 2947 struct getdirentries_args ap; 2948 ap.fd = uap->fd; 2949 ap.buf = uap->buf; 2950 ap.count = uap->count; 2951 ap.basep = NULL; 2952 return getdirentries(p, &ap); 2953 } 2954 2955 /* 2956 * Set the mode mask for creation of filesystem nodes. 2957 */ 2958 #ifndef _SYS_SYSPROTO_H_ 2959 struct umask_args { 2960 int newmask; 2961 }; 2962 #endif 2963 int 2964 umask(p, uap) 2965 struct proc *p; 2966 struct umask_args /* { 2967 syscallarg(int) newmask; 2968 } */ *uap; 2969 { 2970 register struct filedesc *fdp; 2971 2972 fdp = p->p_fd; 2973 p->p_retval[0] = fdp->fd_cmask; 2974 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; 2975 return (0); 2976 } 2977 2978 /* 2979 * Void all references to file by ripping underlying filesystem 2980 * away from vnode. 2981 */ 2982 #ifndef _SYS_SYSPROTO_H_ 2983 struct revoke_args { 2984 char *path; 2985 }; 2986 #endif 2987 /* ARGSUSED */ 2988 int 2989 revoke(p, uap) 2990 struct proc *p; 2991 register struct revoke_args /* { 2992 syscallarg(char *) path; 2993 } */ *uap; 2994 { 2995 register struct vnode *vp; 2996 struct vattr vattr; 2997 int error; 2998 struct nameidata nd; 2999 3000 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 3001 if ((error = namei(&nd)) != 0) 3002 return (error); 3003 vp = nd.ni_vp; 3004 if (vp->v_type != VCHR && vp->v_type != VBLK) { 3005 error = EINVAL; 3006 goto out; 3007 } 3008 if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0) 3009 goto out; 3010 if (p->p_ucred->cr_uid != vattr.va_uid && 3011 (error = suser_xxx(0, p, PRISON_ROOT))) 3012 goto out; 3013 if (vcount(vp) > 1) 3014 VOP_REVOKE(vp, REVOKEALL); 3015 out: 3016 vrele(vp); 3017 return (error); 3018 } 3019 3020 /* 3021 * Convert a user file descriptor to a kernel file entry. 3022 */ 3023 int 3024 getvnode(fdp, fd, fpp) 3025 struct filedesc *fdp; 3026 int fd; 3027 struct file **fpp; 3028 { 3029 struct file *fp; 3030 3031 if ((u_int)fd >= fdp->fd_nfiles || 3032 (fp = fdp->fd_ofiles[fd]) == NULL) 3033 return (EBADF); 3034 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) 3035 return (EINVAL); 3036 *fpp = fp; 3037 return (0); 3038 } 3039 #ifndef _SYS_SYSPROTO_H_ 3040 struct __getcwd_args { 3041 u_char *buf; 3042 u_int buflen; 3043 }; 3044 #endif 3045 3046 SYSCTL_DECL(_vfs_cache); 3047 #define STATNODE(mode, name, var) \ 3048 SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, ""); 3049 3050 static int disablecwd; 3051 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, ""); 3052 3053 static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls); 3054 static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1); 3055 static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2); 3056 static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3); 3057 static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4); 3058 static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound); 3059 int 3060 __getcwd(p, uap) 3061 struct proc *p; 3062 struct __getcwd_args *uap; 3063 { 3064 char *bp, *buf; 3065 int error, i, slash_prefixed; 3066 struct filedesc *fdp; 3067 struct namecache *ncp; 3068 struct vnode *vp; 3069 3070 numcwdcalls++; 3071 if (disablecwd) 3072 return (ENODEV); 3073 if (uap->buflen < 2) 3074 return (EINVAL); 3075 if (uap->buflen > MAXPATHLEN) 3076 uap->buflen = MAXPATHLEN; 3077 buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK); 3078 bp += uap->buflen - 1; 3079 *bp = '\0'; 3080 fdp = p->p_fd; 3081 slash_prefixed = 0; 3082 for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { 3083 if (vp->v_flag & VROOT) { 3084 vp = vp->v_mount->mnt_vnodecovered; 3085 continue; 3086 } 3087 if (vp->v_dd->v_id != vp->v_ddid) { 3088 numcwdfail1++; 3089 free(buf, M_TEMP); 3090 return (ENOTDIR); 3091 } 3092 ncp = TAILQ_FIRST(&vp->v_cache_dst); 3093 if (!ncp) { 3094 numcwdfail2++; 3095 free(buf, M_TEMP); 3096 return (ENOENT); 3097 } 3098 if (ncp->nc_dvp != vp->v_dd) { 3099 numcwdfail3++; 3100 free(buf, M_TEMP); 3101 return (EBADF); 3102 } 3103 for (i = ncp->nc_nlen - 1; i >= 0; i--) { 3104 if (bp == buf) { 3105 numcwdfail4++; 3106 free(buf, M_TEMP); 3107 return (ENOMEM); 3108 } 3109 *--bp = ncp->nc_name[i]; 3110 } 3111 if (bp == buf) { 3112 numcwdfail4++; 3113 free(buf, M_TEMP); 3114 return (ENOMEM); 3115 } 3116 *--bp = '/'; 3117 slash_prefixed = 1; 3118 vp = vp->v_dd; 3119 } 3120 if (!slash_prefixed) { 3121 if (bp == buf) { 3122 numcwdfail4++; 3123 free(buf, M_TEMP); 3124 return (ENOMEM); 3125 } 3126 *--bp = '/'; 3127 } 3128 numcwdfound++; 3129 error = copyout(bp, uap->buf, strlen(bp) + 1); 3130 free(buf, M_TEMP); 3131 return (error); 3132 } 3133