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