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