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